本章概述了監管背後的概念,並提供一些語義的說明。描述如何將其轉換爲實際代碼的詳細信息,請參閱Scala和Java API的相應章節。html
示例項目:你能夠看到在實踐中如何使用akka-samples-supervision-javajava
如Actor Systems監管中所述,描述了Actor之間的依賴關係:主管將任務委託給下屬,所以必須迴應他們的失敗。當下屬檢測到故障(即拋出異常)時,它會暫停自身及其全部下屬,並向其主管發送消息,指示故障。根據要監督的工做性質和失敗的性質,主管能夠選擇如下四種選擇:編程
重要的是始終將一個Actor視爲監督層級的一部分,這解釋了第四個選擇的存在(做爲一個主管也從屬於另外一個上級的主管)而且對前三個有影響:恢復一個Actor恢復它的所有下屬,從新啓動一個actor須要從新啓動它的全部下屬(可是請參閱下面的更多細節),相似地終止一個actor也將終止它的全部下屬。須要注意的是,Actor類的preRestart的默認行爲是在從新啓動以前終止其全部子節點,可是能夠重寫此此方法;遞歸重啓適用於執行此hook後留下的全部子節點。函數
每一個主管配置有一個功能,將全部可能的故障緣由(如:exceptions)轉換爲上面給出的四個選擇之一;值得注意的是,此函數不會將失敗的actor的身份做爲輸入。很容易想出結構的例子,這可能看起來不夠靈活,例如:但願將不一樣的策略應用於不一樣的下屬。在這一點上,理解監督是關於造成遞歸故障處理結構是相當重要的。若是你試圖在一個層面作太多,那將很難推理,所以在這種狀況下推薦的方法是增長必定程度的監督。post
Akka實施了一種稱爲「parental supervisio(父母監督)」的特定形式。Actor只能由其餘Actor建立 - 其中頂級Actor由library提供 - 每一個建立的Actor都由其父級監督。這種限制使得Actor監督等級的造成是隱含的,並鼓勵合理的設計決策。應該指出的是,這也保證了Actor不能從外部成爲孤兒或附屬於監督者,不然可能會讓他們不知不覺。此外,這爲actor應用程序的(子樹)產生了一個天然而乾淨的關閉過程。spa
Actor系統將在其建立過程當中啓動至少三個Actor,如上圖所示。有關actor路徑的後果的更多信息,請參閱Actor路徑的Top-Level Scopes for Actor Paths.。設計
可能與之交互最多的Actor是全部用戶建立的演員的父母,監護人名爲「/ user」。使用system.actorOf()建立的Actor是此actor的子級。這意味着當該監護人終止時,系統中的全部經常使用Actor也將被關閉。這也意味着這個監護人的監督策略決定了頂級Actor的監督方式。從Akka 2.1開始,可使用設置akka.actor.guardian-supervisor-strategy來配置它,該策略採用SupervisorStrategyConfigurator的徹底限定類名。當監護人升級失敗時,根監護人的迴應將是終止監護人,這實際上將關閉整個Actor系統。htm
這個特殊的監護人被引入,以實現有序的關閉序列,其中記錄保持活動,而全部正常的Actor終止,即便記錄自己是使用actor實現的。這是經過讓系統監護人觀察用戶監護人並在接收到終止消息時啓動其本身的關閉來實現的。頂級系統actor使用策略進行監督,該策略將在全部類型的Exception上無限期地從新啓動,除了ActorInitializationException和ActorKilledException,它將終止有問題的子節點。全部其餘throwables都會升級,這將關閉整個actor系統。blog
root guardian是全部所謂的「頂級」Actor的祖母,並使用SupervisorStrategy.stoppingStrategy監督路徑的頂級範圍中提到的全部特殊Actor,其目的是終止任何類型的孩子異常。因爲每一個真正的Actor都有一個主管,root guardian的主管不能成爲真正的Actor。並且由於這意味着它「在泡沫以外」,它被稱爲「bubble-walker」。這是一個合成的ActorRef,它實際上會在遇到麻煩的第一個跡象時阻止其子進程,並在根守護者徹底終止(全部子進程遞歸中止)後當即將actor系統的isTerminated狀態設置爲true。遞歸
當呈如今處理特定消息時失敗的Actor時,失敗的緣由分爲三類:
除非失敗是可識別的,不然不能排除第三個緣由,這致使得出內部狀態須要被清除的結論。若是主管決定其餘孩子或其自己不受失敗影響有意識地應用了錯誤內核模式 - 所以最好重啓子進程。這是經過建立基礎Actor類的新實例並用子項的ActorRef中的新實例替換失敗的實例來實現的;執行此操做的能力是將actor封裝在特殊引用中的緣由之一。而後,新的actor繼續處理其郵箱,這意味着從新啓動在actor自己以外是不可見的,可是沒有從新處理髮生故障的消息。
重啓期間的事件順序以下:
與上述父項和子項之間的特殊關係相反,每一個Actor均可以監視任何其餘Actor。因爲Actor從創做中徹底活躍起來而且在受影響的主管以外看不到重啓,惟一可用於監控的狀態變化是從活着過渡到死亡。所以,監控用於將一個Actor與另外一個Actor聯繫起來,以便它能夠對另外一個Actor的終止做出反應,這與對失敗做出反應的監督相反。
生命週期監視是使用監視actor接收的Terminated消息實現的,其中默認行爲是在沒有另外處理的狀況下拋出特殊的DeathPactException。要開始偵聽Terminated消息,請調用ActorContext.watch(targetActorRef)。要中止偵聽,請調用ActorContext.unwatch(targetActorRef)。一個重要的特性是不管監視請求和目標終止發生的順序如何,都將傳遞消息,即,即便在註冊時目標已經死亡,您仍然會收到消息。
若是主管不能從新啓動其子女而且必須終止它們,監控特別有用,例如:若是在actor初始化期間出錯。在這種狀況下,它應該監視這些孩子並從新建立它們或安排本身稍後重試。
另外一個常見的用例是,在沒有外部資源的狀況下,Actor須要失敗,外部資源也多是其本身的孩子之一。若是第三方經過system.stop(子)方法終止子項或發送PoisonPill,則主管可能會受到影響。
原文地址:https://doc.akka.io/docs/akka/2.5/general/supervision.html