Actor生命周期理解
Actor生命周期理解
鎮圖:Actor內功心法圖
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,在不同的策略下調用次數及順序是不同的,那什麼是策略?:
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策略裏麵會詳細介紹。
Stop策略
postStop hook 一般用於回收資源。Actor在被調用postStop之前,會將郵箱中剩下的message處理掉(新的消息變成死信了)。Actor是由UID和Path來唯一標識的,也就是說ActorRef也是通過UID和Path來定位。在Actor被Stop之後,新的Actor是可以用這個Path的,但是舊的ActorRef是不能用的,因為UID不一樣。
Restart策略
Restart策略是最為複雜的一種情況,先上個圖:
在默認情況下,Restart策略會:
- actor被掛起
- 調用舊實例的 supervisionStrategy.handleSupervisorFailing 方法 (缺省實現為掛起所有的子actor)
- 調用preRestart方法,從上麵的源碼可以看出來,preRestart方法將所有的children Stop掉了!(Stop動作,大家注意!),並調用postStop回收資源
- 調用舊實例的 supervisionStrategy.handleSupervisorRestarted 方法 (缺省實現為向所有剩下的子actor發送重啟請求)
- 等待所有子actor終止直到 preRestart 最終結束
- 再次調用之前提供的actor工廠創建新的actor實例
- 對新實例調用 postRestart
- 恢複運行新的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,使用靜態類保存狀態
最後更新:2017-04-03 05:40:04
上一篇:
linux yum命令詳解
下一篇:
Javascript 學習 筆記一
Spring-Bean的屬性(1.單獨定義BEAN,ID為之的BEAN參考之 2.在BEAN中直接定義參考的BEAN)
(cljs/run-at (JSVM. :all) "Metadata就這樣哦")
新增計費項窄帶高清、外網流出流量計費項
android多點觸摸demo
軟件事務內存導論(六)配置Akka事務
C# DataTable.NewRow 方法
Xen Server虛擬機刪除數據的恢複過程
5招教你用Python構建好玩的深度學習應用
【雲和恩墨大講堂電子期刊】挑戰者:Google成功的背後
ASP.NET Core中的依賴注入(5):ServicePrvider實現揭秘【補充漏掉的細節】