FastTracks / TheAkkaWay

Akka Chinese Book / What should be included in it?
Apache License 2.0
19 stars 3 forks source link

子actor问题 #42

Closed scalaoop closed 7 years ago

scalaoop commented 7 years ago

比如一项任务,我可能由多个子actor,actorA actorB actorC actorD去分开处理任务的一小部分 那么问题来了: 1.子actor如何告知父actor其任务的完成情况? 当所有的子actor都成功完成处理后,又如何告知父actor整个任务已经完成,以便父actor可以通知其它 actor(targetActor)任务已经完成?

2.任何一个子actor处理业务逻辑的时候,都有可能出现异常,比如,其中一个子actor可能是去数据库查数据,此时数据库的网络出现问题了,子actor将无法成功处理业务逻辑。因为这个不是子actor挂掉,而是子actor处理业务逻辑的时候才产生的异常,所以不需要父actor去监管吧?我现在是在try-catch里面处理。 如果是父actor监管,让子actor重启,此时会不会出现消息丢失? 子actor都有可能出现网络异常,我需要在每个子actor中都进行同样的逻辑处理一次么?这样做的话,重复代码太多了。有没有什么高级的做法?比如message pattern

3.个人感觉,如果一个任务,需要多个actor(可能是非parent-child情况)协作完成,当actor数目越多,该任务出现异常的概率越大,是不是我们在设计程序的时候,对参与的actor数目有控制?有什么最佳做法的经验么?

He-Pin commented 7 years ago

不好意思才看到,我分别回答下:

  1. Actor系统中,一般通过领域消息来进行有意义的通信,即这里我们使用JobDone(id:Int)之类的来告知父Actor工作已经完成,单父Actor收到后,如果还需要告知别的,只需要简单的发送消息就好了,当然也可以采用和系统隔离的EventStream来做。
  2. 这里需要注意的是,失败和错误,其中失败,即Failure是你自己不知道的、未处理的情况,这才是Actor的监督机制需要处理的,而错误,即Error你是知道的,所以父Actor不需要介入。你这里自己处理了,就没有父Actor什么事情了。如果在失败的时候,导致了重启,只会丢失当前导致这个异常的消息,而不会导致未被处理的消息丢失。后面部分问题没看懂。
  3. 对数量控制的话一般都是用的Router来做的,也可以自己使用Actor来控制,类似信号量。
Ryan-Cui commented 7 years ago

一个业务需要多个Actor参与的时候,可以将这个业务作为一个任务(Task),使用分散--聚合路由器(Actor),将任务分发下去,再接受各个处理业务的Actor处理结果。当任务完成或超时或反回失败后,将任务的最终结果返回回去。 详细的设计模式可参阅《响应式架构--消息模式Actor实现与Scala、Akka应用集成》这本书中的“分散--聚合路由器”

scalaoop commented 7 years ago

恩 谢谢 回复晚了