1. 程式人生 > >akka學習之actor監護與監控

akka學習之actor監護與監控

       在前面的章節akka學習之actor介紹中介紹了actor對ziactor有監護職責,同時actor對其他actor的生命週期等資訊進行監控。這張將詳細解釋什麼是監護和監控。

什麼是監護(supervision)

在actor系統,一個actor(上司也可以成為監護人)可以建立子actor(下屬),然後可以分配任務給他的下屬去執行,同時也要對下屬的錯誤負責,上司也是下屬的監護者。當下屬發生了錯誤,比如丟擲了一個異常,下屬會終止自己以及它的下屬,然後傳送一個訊息給他的上司(監護人),表示發生了錯誤。根據具體的任務內容以及錯誤的型別,監護人可能會採取下面某種措施:

1.儲存下屬當前的狀態,並讓下屬重試一次。

2.清除下屬的當前狀態,重啟下屬

3.永久的終止下屬

4.把錯誤交給他的監護者來處理,並讓自己處於錯誤狀態。

    要理解akka監護的思想,必須牢記一點:把每一個actor視為整個akka監護層級體系的一部分,因為一個actor可能既是監護者,又是被監護者。終止一個actor,也同時終止了這個actor的所有下屬,同樣重啟一個一個actor也同時重啟了這個actor的所有下屬。actor類的重啟鉤子preRestart方法的預設行為是在重啟前終止它的所有下屬,不過你也可以override這個方法。

      每一個監護者都必須實現一個錯誤處理方法,這個方法使用上面4個措施中的一種來處理所有可能的錯誤,必須注意的是,不要把發生錯誤的actor物件作為這個方法的輸入。但是你可能發現這種錯誤處理的框架可能不夠靈活,比如你想要實現針對不同的下屬使用不同的處理策略。由於akka的監管方式是可以遞迴式得升級,在某個actor上做太多種的監控策略可能會導致你很難排查問題。比如你在一個actor中捕獲並處理了N中不同的exception型別,那麼你排查問題的時候就可能不知道這個異常是它哪個層級的下屬丟擲的。因此最好在系統中加入一個專門的監護層。

       akka的監護方式是一種“父監護”形式,就像父母是兒女的監護人一樣。一個actor的建立只能通過其他的actor來建立(最頂層的actor是akka庫提供的),建立者就是父actor,被建立者是子actor,一個actor的監護人就是建立它的actor。這種自上而下的樹形結構使得akka的監護層級結構更加清晰,同時也保證了一個actor不會成為孤兒,或者擁有父actor之外的監護人。另外,這也使得關閉應用程式的步驟是自下而上逐層關閉,步驟更加清晰。

        父子actor之間監護關係是是通過特殊的系統訊息來連線的,並且這些特殊的訊息有自己單獨的系統郵箱。因此這些特殊的訊息與普通的使用者訊息之間沒有明確的順序,使用者也沒有辦法來干預特殊訊息和使用者訊息之間的順序。

頂層監護者

       一個actor系統建立之後,他至少包含了3個actor:根守護actor,系統守護actor,使用者守護actor。如下圖所示:


/user:使用者守護actor 

       所有使用者actor的根actor都是使用者守護actor,是使用者建立的一個層級的actor的父actor和監護者,它的名字就是“/user”,所有通過system.actorOf()方法建立的actor都是他的子actor。當用戶守護actor停止了,所有的使用者建立的actor也將會停止,同時它的監護策略也決定了使用者建立的第一層actor的錯誤是如何被處理的。在akka2.1之後的版本中可以通過akka.actor.guardian-supervisor-strategy(它使用SupervisorStrategyConfigurator的完整類名)來配置它的監護策略。當用戶守護actor向它的監護者根守護actor提交了一個錯誤,根守護將會停止使用者守護actor,進而關閉整個actor系統。

/system:系統守護actor

      在應用中,我們常常需要使用日誌來記錄整個系統模組的關閉順序和行為,因此日誌模組會在所有的actor停止之前還在工作,即使日誌模組本身也是一個actor。為了實現這個功能,需要一個系統守護者來保證日誌模組在最後關閉,已經管理整個系統在接收到停止訊息之後的關閉行為。系統守護actor的監護策略是,在接收到除 ActorInitializationException 和ActorKilledException的所有異常時會提交到根守護者然後重啟整個系統,ActorInitializationException 和ActorKilledException會停止發生錯誤的子actor。

/:根守護actor

根守護actor是所有所謂的頂層actor的祖父,它監護著所有的特殊actor,它的監護策略SupervisorStrategy.stoppingStrategy,它不管收到什麼異常,都關閉出問題的子actor。前面說過每一個actor都有自己的監護者,但是根守護actor是整個系統的起點,那麼它的監護者是誰呢?其實根守護actor是一個虛擬的actor引用,它會停止第一個向它彙報錯誤的子actor,然後在整個actor系統都停止之後把actor系統的isTerminated狀態設定為true。

重啟(restarting)的含義

    導致actor處理某個訊息時發生錯誤的情況,大致可以分為3類:

1.處理某個訊息時發生系統錯誤,比如資料不合法,導致空指標異常,型別轉換錯誤等等。

2.依賴的外部資源發生錯誤

3.actor內部狀態崩了

   第3種錯誤很難區分具體的情況,除非能夠明確知道哪種錯誤,否則需要直接reset內部狀態。如果監護者能確定某個子actor的錯誤不會對監護者本身以及其他子actor造成影響,那麼最好重啟這個錯誤actor。重啟actor實際上就是重新建立一個這個actor的例項,並且把個actor的actor引用指向新的例項。這也是前面actor介紹中講述的為什麼actor要封裝在actor引用裡面的原因。然後新的actor例項重新開始出來郵箱中的訊息,不過導致就的actor發生錯誤的那條訊息不會再重新處理。所以actor的重啟對外界來說是透明的。actor重啟的精確的流程如下:

1.停止這個actor,不再處理任何訊息,並且遞迴地停止它所有的子actor。

2.呼叫舊這個actorpreRestart鉤子,預設行為是傳送終止請求給所有的子actor,並且呼叫postStop鉤子執行停止之後的行為。

3.等待所有接收到終止訊息的子actor完全終止,當然這個等待是非阻塞的,只有最後一個終止的子actor傳送終止訊息訊息過來之後,才開始執行下一步。

4.通過原來提供的actor工廠建立一個新的actor例項。

5.在新的例項中呼叫postRestart鉤子(預設行為是呼叫preStart鉤子)。

6.傳送重啟請求給所有在第3步中被殺死的子actor,遞迴地從第2步開始重啟所有子actor。

7.重新開始執行actor的訊息處理行為。

生命週期監控

    上面講的監護關係是一種相當於父母對子女的監護關係,即只有建立它的父actor才能監護它。而監控(monitor)則不侷限於血緣關係,只要一個actor能拿到另一個actor的引用,就可以監控它。由於actor活著創建出來以及重啟對於監護者之外的actor是不可見的,所以監控者能到監控到的狀態變化只能是從生到死的變化。相比於監護者是對被監護者的錯誤做出反應,而監控者是對被監控者的終止做出處理。

    生命週期的監控是通過監控者接收被監控者傳送的終止訊息來實現的。預設的是實現是丟擲一個DeathPactException異常。開始終止訊息的監聽是通過ActorContext.watch(targetActorRef)來實現,而停止終止訊息的監聽則是呼叫ActorContext.unwatch(targetActorRef)。需要注意的是,終止訊息的傳遞與被監控者終止行為的發生是沒有順序的,所以及時事實上被監控actor已經終止,監控者還是需要繼續接收終止訊息。

    當監護者不能通過簡單的重啟來恢復子actor而不得不終止它,那麼監控就顯得尤為重要。比如actor初始化錯誤,這種情況下就必須監控這些子actor,以便重新建立或者定期重試actor。另外一個監控比較有用和常見的場景是actor可能遇到所依賴的外部資源的缺失。當然也可能是它自己的子actor的缺失,比如第三方通過system.stop(child)方法或者致命毒丸終止了它的子actor,父actor也會受到影響。

 一對一策略與全部對一策略

       在阿akka中,監護策略大致可以分為兩類:一對一策略與全部對一策略。這兩類策略的使用都是通過配置監護者策略與對應的異常型別匹配,以及子actor在停止前允許發生的錯誤次數來實現。一對一策略是隻對發生錯誤的子actor進行處理,而全部對一策略則是對發生錯誤的actor的兄弟姐妹也進行處理。

       一般情況下使用一對一策略就可以了,同時akka的預設方式也是一對一。全部對一策略的適用場景是actor的組裝互相依賴於它的兄弟姐妹,這種場景下一個actor的錯誤會導致它的兄弟姐妹也發生錯誤。因為重啟不會情況郵箱中的訊息,所以最好是終止並且重建發生錯誤的actor,否則你要確保重啟之後郵箱中的訊息不會導致actor繼續發生錯誤,不然你的actor將陷入無休止的重啟中。

       在全部對一策略中一般終止一個子actor並不會自動的終止其他子actor。但是可以簡單地通過監控生命週期來實現:如果監護者沒有處理終止訊息,監護者將丟擲一個DeathPactException 並且重啟自己,它預設的preRestart 方法將停止所有的子actor。當然也可以明確定義處理方法來實現。

    必須注意到,如果在使用全部對一策略的監護者中建立一次性的actor,那麼這個臨時性的actor發生錯誤會影響那麼永久性的actor。如果不想這種情況發生,那麼應該建立一箇中間監護者:這很容易通過為工作者宣告一個size為1的路由實現。

相關推薦

akka學習actor監護監控

       在前面的章節akka學習之actor介紹中介紹了actor對ziactor有監護職責,同時actor對其他actor的生命週期等資訊進行監控。這張將詳細解釋什麼是監護和監控。 什麼是監護(supervision) 在actor系統,一個actor(上司也可以成為監護人)可以建立子actor(下

分散式架構學習:007--Dubbo 監控中心的介紹簡易監控中心的安裝

Dubbo 監控中心的介紹與簡易監控中心的安裝 一、監控中心的作用      監控中心主要負責統計各服務呼叫次數,呼叫時間等,統計先在記憶體中彙總後每分鐘傳送到中心伺服器,並以報表展示。為服務的監控

機器學習SVM初解淺析(一):最大距離

機器學習 svm 最大距離 2 / ||w|| 這段時間在看周誌華大佬的《機器學習》,在看書的過程中,有時候會搜搜其他人寫的文章,對比來講,周教授講的內容還是比較深刻的,但是前幾天看到SVM這一章的時候,感覺甚是晦澀啊,第一感覺就是比較抽象,特別是對於像本人這種I

機器學習SVM初解淺析(一):

機器學習 svm 最大距離 2 / ||w||sdsshngshan‘gccha 這段時間在看周誌華大佬的《機器學習》,在看書的過程中,有時候會搜搜其他人寫的文章,對比來講,周教授講的內容還是比較深刻的,但是前幾天看到SVM這一章的時候,感覺甚是晦澀啊,第一感覺就

機器學習決策樹隨機森林模型

會有 strong pytho red -s 很多 4.5 是我 機器 歡迎大家前往騰訊雲技術社區,獲取更多騰訊海量技術實踐幹貨哦~ 作者:汪毅雄 導語 本文用容易理解的語言和例子來解釋了決策樹三種常見的算法及其優劣、隨機森林的含義,相信能幫助初學者真正地理解相關知識

Redis學習發布訂閱機制

tom ger 取消 scribe mes 技術 超時 兩個 order Redis提供了發布訂閱功能,可以用於消息的傳輸,Redis的發布訂閱機制包括三個部分,分別是發布者、訂閱者、頻道(channel)。註意:redis屬於即發即棄的機制,信息發送後則會丟失,如果訂閱者

Linux學習用戶root

使用 pwd 如何 但是 images 。。 圖片 不能 localhost 因為想要建立建立一個目錄,但是發現權限不夠,因為沒用root登陸,所以學習了一下普通用戶與root之間如何切換以及如何創建用戶的一些知識。 1、pwd命令可以查看當前用戶

Gradle學習構建javaweb項目

jcenter yun 接口 webxml oot conf ava getc clas 一.使用Gradle的java插件構建Java項目 1)Gradle插件包含了若幹個接口定義和已有的任務項,語法結構:apply plugin:‘插件名‘ ,此處我們定義插件

Vue學習v-ifv-show的區別

css屬性 綁定 strong 似的 表達式 他會 根據 als 相對 v-if和v-show具有類似的功能,不過v-if才是真正的條件渲染,他會根據表達式適當的銷毀或重建元素及綁定事件或子組件。若表達式初始值為false,則一開始元素或組件不會渲染,只有當第一次為真時,才

Python學習-序列化反序列化

什麽是 註意 not 技術分享 js對象 字節 com 操作 是個 1、什麽是序列化與反序列化? # 我們把對象(或變量)從內存變成可存儲或可傳輸的過程稱之為序列化,在python中被稱為picking; # 自定義的類的實例如何保存在一個文件中?如何從文件中讀取數據,並讓

JS學習賦值賦引用

內容 當前 都沒有 分享 img 定義 con png 技術分享 1、基本類型 基本的數據類型有:undefined,boolean,number,string,null。 基本類型存放在棧區,訪問是按值訪問的,就是說你可以操作保存在變量中的實際的值。 當基本類型的數據賦

C++基礎學習記憶體模型名稱空間(5)

單獨編譯 將程式分為三個部分: 標頭檔案:包含結構宣告和使用這些結構的函式的原型。 原始碼檔案:包含與結構有關的函式的程式碼。 原始碼檔案:包含呼叫與結構相關的函式的程式碼。 一般儘量避免將函式定義或變數宣告放到標頭檔案中,防止出現重複定義的問題。 標頭

機器學習----目標檢測目標跟蹤的區別

1.目標檢測就是檢測出一個圖片或者一個視訊中目標的位置(靜態或者動態)如yolo檢測目標 2.目標追蹤是給視訊中第一幀目標以及它的位置,然後跟蹤這個目標,以及預測它的軌跡,(如果出現一些遮擋,也可以根據軌跡來跟蹤這個目標,假如是yolo檢測出的目標,有時候還會出現丟幀的情況,如果用了跟蹤演算法,

機器學習---似然概率

“概率”描述了給定模型引數後,描述結果的合理性,而不涉及任何觀察到的資料。 拋一枚均勻的硬幣,拋20次,問15次拋得正面的可能性有多大? 這裡的可能性就是”概率”,均勻的硬幣就是給定引數θ=0.5 ,“拋20次15次正面”是觀測值O。求概率P(H=15|θ=0.5)=

[三]機器學習決策樹隨機森林

3.1 目標任務 1.學習決策樹和隨機森林的原理、特性 2.學習編寫構造決策樹的python程式碼 3.學習使用sklearn訓練決策樹和隨機森林,並使用工具進行決策樹視覺化 3.2 實驗資料 資料集:鳶尾花資料集,詳情見[機器學習之迴歸]的Logistic迴歸實驗 3.3

mysql學習資料庫管理表管理

資料庫管理 3.1 查詢所有資料庫 mysql> show databases; 3.2 建立資料庫 mysql> create database emp       -- 指定預設字符集建立資料庫   &n

Unity3d學習路-牧師魔鬼V2(動作分離版)

Unity3d學習之路-牧師與魔鬼V2(動作分離版) 該版本改進的目的 把每個需要移動的遊戲物件的移動方法提取出來,建立一個動作管理器來管理不同的移動方法。 對於上一個版本,每一個可移動的遊戲物件的元件都有一個Move指令碼,當遊戲物件需要移動時

Flask學習基礎知識功能

一:flask的背景介紹 Flask是一個基於Python開發並且依賴jinja2模板和Werkzeug WSGI服務的一個微型框架,對於Werkzeug本質是Socket服務端,其用於接收http請求並對請求進行預處理,然後觸發Flask框架,開發人員基於Flask框架提供的功能對請求進行相應的處理,並返

QT學習路---訊號槽問題解析

前兩天用到了QT的訊號與槽這個機制,剛開始發射訊號的時候,我是這麼寫的語句 connect(sender,SINGAL(),receiver,SLOT()) 由於我用的是QT 5.11這個本,從網上查到的例子來說,大部分都是以上那個形式,也沒有問題,而實際上在QT5.11版本上,向下面這樣寫

機器學習模型評估引數調優

一、流水線工作流        在利用訓練資料對模型進行擬合時已經得到一些引數,使用流水線可以避免在將模型用於新資料時重新設定這些引數。利用sklearn中的Pipline類,使得我們可以擬合出包含任意多個處理步驟的模型,並將模型用於新資料的預測。 1. # Title