閱讀792 返回首頁    go 阿裏雲 go 技術社區[雲棲]


AKKA文檔(java版)—什麼是角色

2.3 什麼是角色?
前麵角色係統一節介紹了一群角色如何形成一個層次結構,並且介紹了角色是構建應用程序的最小單位。本節我們將角色拿出來單獨介紹,解釋一些你在使用它的過程中可能遇到的概念。對於一些更深入的細節,將會在後麵的章節中詳細介紹。
你可以將角色想象成一個容器,它其中包括狀態,行為,一個信箱,子角色以及一個監管策略。所有這些都封裝在一個角色引用中。本節的最後介紹一個角色什麼時候終結。


2.3.1 角色引用
如下所述,為了更好的發揮角色模式的優勢,一個角色對象需要與外部隔離。因此,在外部通過一個角色引用來表示角色對象,這些角色對象引用可以自由的傳遞而不受約束。這種將對象劃分為內部對象和外部引用的好處是可以使下列操作透明化:重啟一個角色不需要更新角色引用,角色可以在遠程機器上,可以通過完全不同的應用來給角色發消息。並且這樣做最重要的好處是,外部的對象永遠無法得到角色內部的狀態,除非角色不明智的公開了它的信息。
2.3.2 狀態
角色對象通常都包含一些變量來表明它當下處於哪個狀態。這些變量可以是顯示的狀態機(例如,使用fsm-scala模型),也可以是一個計數器,一組監聽器,甚至等待掛起等。正是這些狀態數據使得角色有價值,因此必須保護它們不被其他的角色破壞。好消息是從概念上來講每個Akka角色對象都有它自己的輕量級線程,而這個線程是與係統的其他部分完全隔離的。這也就意味著你可以放心大膽的寫你的角色代碼而不用考慮並發的同步問題。
在後台Akka會有一係列的真實線程來運行這一係列的角色,如有些情況下多個角色會共用一個線程。因而一個角色在接下來的調用中可能會被另一個不同的線程所處理。但是無論實現細節是怎麼樣的,Akka都能確保同時隻有一個線程去改變角色的狀態。
角色的內部狀態對它的行為是至關重要的,如果出現狀態不一致將會產生致命的錯誤。因而,當一個角色失敗並被它的監管程序重啟時,它的狀態將被重新初始化。而這一點也使得係統有了自動恢複的能力。
可選擇地,一個角色也可以在重啟後通過重新處理那些老的消息來恢複到它重啟之前的狀態(參考 persisitence-scala)。

2.3.3 行為
每次消息的處理都會與角色當前的行為所匹配。行為指的是一個函數定義的在當前狀態下對一條消息所要采取的行動。例如如果這個客戶端是經過認證的則轉發它的請求,否則拒絕。並且行為可能隨著時間的不同而變化,例如,某些客戶端可能在後來獲得了認證,或者角色先在“不在服務狀態”的模式後來又恢複服務了等等。這些變化可能是因為狀態變量的變化引起的,也可能是函數在運行時被換出引起的,參考become 和unbecome操作。然而,角色對象重啟後都會恢複到構造函數中初始化的行為。

2.3.4 信箱
角色的任務是處理來自其他角色(或者角色係統之外)發來的消息。連通消息發送者和接受著的對象就是信箱:每個角色都有一個信箱,發送者將消息發送到該信箱。消息以發送者發送消息的時間順序入隊,這也就意味著由於發送者在線程上分布的隨機性,來自不同角色的消息在運行時沒有一個確定的入隊順序。但是同一個發送者發送的消息順序是一定的。
這裏有很多不同的信箱實現方式可供選擇,默認的方式是FIFO:消息被處理的順序和消息入隊的順序相同。通常我們都選擇默認的實現方式,但是有些應用程序可能需要對一些消息優先處理。在這種情況下,消息入隊的時候就不一定是插在隊尾了,而是根據它的優先級插入到對應的位置,優先級特別高甚至可能直接插在隊頭。當使用這種隊列時,消息被處理的順序決定於該隊列的實現算法,並且通常不是FIFO.
Akka不同於其他角色模型實現的一個重要特征是當前的行為必須挨個處理隊列裏的下一個消息,它並不會去掃描信箱以得到一個匹配的消息。無法處理消息就會被認為是失敗,除非當前的行為是忽略此消息。

2.3.5 子角色
每個角色都是一個潛在的監督員:一旦它創建了子角色並且賦予了它一個子任務,那麼它將自動監管這些子角色。角色在它的上下文環境(context)中維持著一個子角色列表,以便隨時訪問它們。角色通過創建(context.actorOF(…))或停止(context.stop(child))命令來修改這個列表。並且這個修改立馬就會生效。這個創建和終止命令是以異步的方式實現的,所以它不會阻塞監督者。

2.3.6 監督者策略
角色最後一個功能是處理子角色的故障。故障處理對於用戶來說是透明的,對於發生的故障Akka都會自動的通過對應策略處理(監管和監測章節介紹)。 因為這些策略是構成角色係統的基礎,所以一旦角色被創建那麼這些故障處理策略將不可改變。
由於每個角色都隻有一類故障處理策略,這也就意味著不同的子角色將會應用不同的策略。角色根據子角色所使用的故障處理策略將它們分組。根據任務被切分的子任務性質係統會不斷的重複這個分組過程。

2.3.7 什麼時候角色終止
一旦角色終止,如失敗後無法重啟,自己停止或者被監督者停止,那麼它將釋放它占有的所有資源,並將它信箱中沒處理的消息發送到“死信件信箱”裏,然後“死信件信箱”將會把他們以DeadLetters的形式傳遞給EventStream. Actor引用中的信箱將會被一個係統信箱所取代,然後將所有消息以DeadLetters的形式轉發給EventStream。雖然係統會盡最大努力來實現該消息傳遞,但是我們不能依賴它來實現“有保證的傳遞”。
為什麼不選擇悄悄的將所有消息傾倒出來,是基於我們下麵的測試結果考慮:我們在事件總線(BUS)上注冊了測試事件監聽器(TestEventListener)。這裏事件總線即死信件被發送到的地方。該監聽器將會對收到的每條死信件記錄一條警告日誌——這個可以幫助我們更快的檢測失敗。所以我們有理由相信這個特征還將可以應用於其他目的。

 

譯者注:本人正在翻譯AKKA官網文檔,本篇是文檔第二章,歡迎有興趣的同學加入一起翻譯。更多內容請讀這裏:https://tower.im/projects/ac49db18a6a24ae4b340a5fa22d930dc/todos/640e53d6e8c149ab95c47cd333b91073/
(全文完)如果您喜歡此文請點讚,分享,評論。

最後更新:2017-05-23 16:34:01

  上一篇:go  手把手 | 初學者如何用Chainer為漫畫上色 深度學習幫你逆襲漫畫家(附代碼)
  下一篇:go  JVM 性能優化,第二部分:編譯器