Actor的生命周期
在Actor系统中的路径代表一个“地方”,这可能被一个存活着的的actor占用着。最初,路径(除了系统初始化角色)是空的。当actorOf()
被调用时,指定一个由通过Props
描述给定的路径角色的化身。一个actor化身由路径和一个UID确定。重新启动仅仅交换Props定义的Actor 实例,但化身与UID依然是相同的。
当该actor停止时,化身的生命周期也相应结束了。在这一刻时间上相对应的生命周期事件也将被调用和监管角色也被通知终止结束。化身被停止之后,路径也可以重复被通过actorOf()
方法创建的角色使用。在这种情况下,新的化身的名称跟与前一个将是相同的而是UIDs将会有所不同。
一个ActorRef
总是代表一个化身(路径和UID)而不只是一个给定的路径。因此,如果一个角色停止,一个新的具有相同名称创建的旧化身的ActorRef
不会指向新的。
在另一方面ActorSelection
指向该路径(或多个路径在使用通配符时),并且是完全不知道其化身当前占用着它。由于这个原因导致ActorSelection
不能被监视到。通过发送识别信息到将被回复包含正确地引用(见通过角色选择集识别角色)的ActorIdentity
的ActorSelection
来解决当前化身ActorRef
存在该路径之下。这也可以用ActorSelection
类的resolveOne
方法来解决,这将返回一个匹配ActorRef
的Future
。
Actor生命周期Hook:
Akka Actor定义了下列的生命周期回调钩子(Hook):
- preStart:在actor实例化后执行,重启时不会执行。
- postStop:在actor正常终止后执行,异常重启时不会执行。
- preRestart:在actor异常重启前保存当前状态。
- postRestart:在actor异常重启后恢复重启前保存的状态。当异常引起了重启,新actor的postRestart方法被触发,默认情况下preStart方法被调用。
启动Hook
启动策略,调用preStart Hook,一般用于初始化资源.在创建一个Actor的时候,会调用构造函数,之后调用preStart。
preStart的默认形式:
def preStart(): Unit = ()
重启Hook
所有的Actor都是被监管的,i.e.以某种失败处理策略与另一个actor链接在一起。如果在处理一个消息的时候抛出的异常,Actor将被重启。这个重启过程包括上面提到的Hook:
- 要被重启的actor的
preRestart
被调用,携带着导致重启的异常以及触发异常的消息; 如果重启并不是因为消息的处理而发生的,所携带的消息为None,例如,当一个监管者没有处理某个异常继而被它自己的监管者重启时。 这个方法是用来完成清理、准备移交给新的actor实例的最佳位置。它的缺省实现是终止所有的子actor并调用postStop
。- 最初
actorOf
调用的工厂方法将被用来创建新的实例。- 新的actor的
postRestart
方法被调用,携带着导致重启的异常信息。
actor的重启会替换掉原来的actor对象;重启不影响邮箱的内容, 所以对消息的处理将在postRestart hook
返回后继续。触发异常的消息不会被重新接收。在actor重启过程中所有发送到该actor的消息将象平常一样被放进邮箱队列中。
preRestart和postRestart的默认形式:
def preRestart(reason: Throwable, message: Option[Any]): Unit = {
context.children foreach { child ⇒
context.unwatch(child)
context.stop(child)
}
postStop()
}
def postRestart(reason: Throwable): Unit = {
preStart()
}
解释一下重启策略的详细内容:
- actor被挂起
- 调用旧实例的 supervisionStrategy.handleSupervisorFailing 方法 (缺省实现为挂起所有的子actor)
- 调用preRestart方法,从上面的源码可以看出来,preRestart方法将所有的children Stop掉了,并调用postStop回收资源
- 调用旧实例的supervisionStrategy.handleSupervisorRestarted方法(缺省实现为向所有剩下的子actor发送重启请求)
- 等待所有子actor终止直到 preRestart 最终结束
- 再次调用之前提供的actor工厂创建新的actor实例
- 对新实例调用 postRestart
- 恢复运行新的actor
终止Hook
postStop hook
一般用于回收资源。Actor在被调用postStop之前,会将邮箱中剩下的message处理掉(新的消息变成死信了)。Actor是由UID和P