[轉] 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策略,調用preStart Hook,通常用於初始化資源.在建立一個Actor的時候,會調用構造函數,以後調用preStart,那這兩個方法有什麼區別呢,資源初始化是放在構造函數,仍是放在preStart裏面呢?在Restart策略裏面會詳細介紹。spa
postStop hook 通常用於回收資源。Actor在被調用postStop以前,會將郵箱中剩下的message處理掉(新的消息變成死信了)。Actor是由UID和Path來惟一標識的,也就是說ActorRef也是經過UID和Path來定位。在Actor被Stop以後,新的Actor是能夠用這個Path的,可是舊的ActorRef是不能用的,由於UID不同。.net
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會將全部的Children經過Stop策略中止,這個時候Children就是經過Stop策略->Start策略啓動的,而不是被遞歸Restart.那有什麼影響?若是有外部的Actor持有舊的Chidren ActorRef,那這個Ref就是不能用的,由於雖然Path是對的,可是UID已經變了!
默認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() }
經過將state轉儲到:
數據庫(案例:Hbase,也是鄭草原的實時計算集羣採用的持久化方法)官方的包akka-persistence-experimental(測試階段), ppt介紹 and Persistence文檔非JVM級別的crash,使用靜態類保存狀態。