什么是Supervision
在之前介绍Actor Model的文章中提到了,上级Actor对于它的下级Actor有监管作用:因为下级Actor的任务是上级Actor分配的,因此当下级Actor出错的时候,上级Actor必须做出回应。当一个Actor监测到异常的发生,它会挂起自己和它的所有下级Actor(所谓的挂起应该就是指不再执行任何任务),并且发送消息到它的监督者(也就是它的上级)表明自己出现了异常。监督者对错误做出相应的处理。
Supervision策略
监督者面对其下属的失败,有不同的策略。不过大致可以分为已下的四类:
1)恢复下级Actor,并且保持下级Actor的内部状态
2)重新启动下级Actor,并且清除下级Actor的内部状态
3)永久的停止下级Actor
4)将错误逐层上传,从而暂停自己(有点像java中的throw exception)
其中需要知道的是,Akka中的每一个Actor都在监督树中,他们既可以扮演监督者的角色,也可以扮演被监督者的角色。上级Actor的状态直接影响着下级Actor的状态,因此对上面的前三条策略可以做如下补充(诠释)
1)当恢复某个Actor的时候同时也要恢复它的所有下级Actor
2)重新启动某个Actor的时候也要重启它所有的下级Actor
3)停止某个Actor的时候也需要停止它所有的下级Actor。
Actor的preRestart方法的默认行为就是:在这个Actor重启前,先终止它所有的下级Actor,这个过程其实就是一个递归的过程。但是这个方法是可以重写的,因此在重写的时候需要谨慎。
UntypedActor中preRestart方法,
/**
* User overridable callback: '''By default it disposes of all children and then calls `postStop()`.'''
* <p/>
* Is called on a crashed Actor right BEFORE it is restarted to allow clean
* up of resources before Actor is terminated.
*/
@throws(classOf[Exception])
override def preRestart(reason: Throwable, message: Option[Any]): Unit = super.preRestart(reason, message)
继续调用父类的preRestart方法,也就是Actor中的方法。
Actor中的preRestart方法, /**
* User overridable callback: '''By default it disposes of all children and then calls `postStop()`.'''
* @param reason the Throwable that caused the restart to happen
* @param message optionally the current message the actor processed when failing, if applicable
* <p/>
* Is called on a crashed Actor right BEFORE it is restarted to allow clean
* up of resources before Actor is terminated.
*/
@throws(classOf