[转] Actor生命周期理解

[转] https://blog.csdn.net/wsscy2004/article/details/38875065数据库

 

镇图:Actor内功心法图ide

Actor的生命周期能够用Hooks体现和控制,下面是默认的Actor Hooks的方法,咱们能够选择性的进行重写:函数

def preStart(): Unit = ()

def postStop(): Unit = ()

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() }

 

每一个Hooks,在不一样的策略下调用次数及顺序是不一样的,那什么是策略?:post

class DbSupervisor extends Actor {
  override def supervisorStrategy = OneForOneStrategy() {
    //若是dbWriter失败,则调用Restart策略,重启该出错的Actor
    case _: DbBrokenConnectionException => Restart
  }
}

 

策略,好比Restart,实际上就是执行了一系列的方法包括:preRestart,postRestart测试

 

Start策略

Start策略,调用preStart Hook,通常用于初始化资源.在建立一个Actor的时候,会调用构造函数,以后调用preStart,那这两个方法有什么区别呢,资源初始化是放在构造函数,仍是放在preStart里面呢?在Restart策略里面会详细介绍。spa


Stop策略

postStop hook 通常用于回收资源。Actor在被调用postStop以前,会将邮箱中剩下的message处理掉(新的消息变成死信了)。Actor是由UID和Path来惟一标识的,也就是说ActorRef也是经过UID和Path来定位。在Actor被Stop以后,新的Actor是能够用这个Path的,可是旧的ActorRef是不能用的,由于UID不同.net


Restart策略

Restart策略是最为复杂的一种状况,先上个图:code

 

在默认状况下,Restart策略会:blog

1. actor被挂起
2. 调用旧实例的 supervisionStrategy.handleSupervisorFailing 方法 (缺省实现为挂起全部的子actor)
3. 调用preRestart方法,从上面的源码能够看出来,preRestart方法将全部的children Stop掉了!(Stop动做,你们注意!),并调用postStop回收资源
4. 调用旧实例的 supervisionStrategy.handleSupervisorRestarted 方法 (缺省实现为向全部剩下的子actor发送重启请求)
5. 等待全部子actor终止直到 preRestart 最终结束
6. 再次调用以前提供的actor工厂建立新的actor实例
7. 对新实例调用 postRestart
8. 恢复运行新的actor

 


Restart策略,和Stop策略有什么不一样的地方?继承

Stop策略会调用postStop(),Restart策略也会调用postStop(),可是Restart策略不是经过Stop策略来中止旧的Actor,UID和Path都没变。也就是说,在被Restart以后,不用从新获取ActorRef.

 

preRestart Hook有什么特别之处?

默认的preRestart Hook会将全部的Children经过Stop策略中止,这个时候Children就是经过Stop策略->Start策略启动的,而不是被递归Restart.那有什么影响?若是有外部的Actor持有旧的Chidren ActorRef,那这个Ref就是不能用的,由于虽然Path是对的,可是UID已经变了!

 

postRestart Hook有什么特别之处?

默认postRestart是调用preStart(),这样在重启的过程当中,构造函数和preStart方法都会被从新调用,若是有个资源只想初始化一次,那么就必须重写掉这个方法.因此通常建立children是放在preStart里面。

override def preStart(): Unit = {
// 初始化children
}

// 重写postRestart防止preStart每次重启都被调用
override def postRestart(reason: Throwable): Unit = ()


override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
  // 任然要清理本身,可是不Stop children
  postStop()
}

 


被重启后,如何继承旧的actor的状态?

经过将state转储到:

数据库(案例:Hbase,也是郑草原的实时计算集群采用的持久化方法)官方的包akka-persistence-experimental(测试阶段), ppt介绍 and Persistence文档非JVM级别的crash,使用静态类保存状态。

相关文章
相关标签/搜索