1. 程式人生 > >一 Akka學習 - actor

一 Akka學習 - actor

system gic map dispatch complete join rand 廣泛 應用程序

(引用 http://shiyanjun.cn/archives/1168.html)

一: 什麽是Akka?

Akka是JAVA虛擬機JVM平臺上構建高並發、分布式和容錯應用的工具包和運行時,是一個框架。Akka用Scala語言寫成,同時提供了Scala和JAVA的開發接口。

Akka處理並發的方法基於Actor模型。在Akka裏,Actor之間通信的唯一機制就是消息傳遞。

二: 什麽是Actor?

維基百科這樣定義Actor模型:

在計算科學領域,Actor模型是一個並行計算(Concurrent Computation)模型,它把actor作為並行計算的基本元素來對待:為響應一個接收到的消息,一個actor能夠自己做出一些決策,如創建更多的actor,或發送更多的消息,或者確定如何去響應接收到的下一個消息。

Actor是Akka中最核心的概念,它是一個封裝了狀態和行為的對象,Actor之間可以通過交換消息的方式進行通信,每個Actor都有自己的收件箱(Mailbox)。
通過Actor能夠簡化鎖及線程管理,可以非常容易地開發出正確地並發程序和並行系統,Actor具有如下特性:

    • 提供了一種高級抽象,能夠簡化在並發(Concurrency)/並行(Parallelism)應用場景下的編程開發
    • 提供了異步非阻塞的、高性能的事件驅動編程模型
    • 超級輕量級事件處理(每GB堆內存幾百萬Actor)

actorOf:除了/system路徑下面的Actor外,一個Actor初始時路徑為空,調用ActorSystem的actorOf方法創建一個Actor實例,返回一個引用ActorRef,它包括一個UID和一個Path,標識了一個Actor,可以通過該引用向該Actor實例發送消息。

ActorSystem:在Akka中,一個ActorSystem是一個重量級的結構,他需要分配多個線程,所以在實際應用中,按照邏輯劃分的每個應用對應一個ActorSystem實例。

Supervisor:ActorSystem是具有分層結構(Hierarchical Structure)的:一個Actor能夠管理(Oversee)某個特定的函數,他可能希望將一個task分解為更小的多個子task,這樣它就需要創建多個子Actor(Child Actors),並監督這些子Actor處理任務的進度等詳細情況,實際上這個Actor創建了一個Supervisor來監督管理子Actor執行拆分後的多個子task,如果一個子Actor執行子task失敗,那麽就要向Supervisor發送一個消息說明處理子task失敗。需要知道的是,一個Actor能且僅能有一個Supervisor,就是創建它的那個Actor。基於被監控任務的性質和失敗的性質,一個Supervisor可以選擇執行如下操作選擇:

  1. 重新開始(Resume)一個子Actor,保持它內部的狀態
  2. 重啟一個子Actor,清除它內部的狀態
  3. 終止一個子Actor
  4. 擴大失敗的影響,從而使這個子Actor失敗

   將一個Actor以一個監督層次結構視圖來看是非常重要的,因為它詮釋了上面第4種操作選擇的存在性,而且對前3種操作選擇也有影響:重新開始(Resume)一個Actor,則該Actor的所有子Actor都繼續工作;重啟一個Actor,則該Actor的所有子Actor都被重新啟動;終止一個Actor,則該Actor的所有子Actor都被終止。另外,一個Actor的preRestart方法的默認行為是終止所有子Actor,如果我們不想這樣,可以在繼承Actor的實現中重寫preRestart方法的邏輯

TypedActor:??

Cluster:

Akka Cluster提供了一個容錯(Fault-Tolerant)、去中心化(Decentralized)、基於P2P的集群服務,而且不會出現單點故障(SPOF, Single Point Of Failure)。Akka基於Gossip實現集群服務,而且支持服務自動失敗檢測。
關於Gossip協議的說明,維基百科說明如下所示:

Gossip協議是點對點(Computer-to-Computer)通信協議的一種,它受社交網絡中的流言傳播的特點所啟發。現在分布式系統常常使用Gossip協議來解決其他方式所無法解決的問題,或者是由於底層網絡的超大特殊結構,或者是因為Gossip方案是解決這類問題最有效的一種方式。

一個Akka集群由一組成員節點組成,每個成員節點通過hostname:port:uid來唯一標識,並且每個成員節點之間是解耦合的(Decoupled)。一個Akka應用程序是一個分布式應用程序,它具有一個Actor的集合S,而每個節點上可以啟動這個Akka應用S的集合的的一部分Actor,而不必是全集S。如果一個新的成員節點需要加入到Akka集群,只需要在集群中任意一個成員節點上執行Join命令即可。
Akka集群中各個成員節點之間的狀態關系,如下圖所示:
技術分享圖片
Akka集群中任何一個成員節點都有可能成為集群的Leader,這是基於Gossip收斂(Convergence)過程得到的確定性結果,沒有經過選舉的過程。Leader只是一種角色,在各輪Gossip收斂過程中Leader是不斷變化的。Leader的職責是使成員節點進入/離開集群。
一個成員節點開始於joining狀態,一旦所有其節點都看到了該新加入Akka集群的節點,則Leader會設置這個節點的狀態為up。
如果一個節點安全離開Akka集群,可預期地它的狀態會變為leaving狀態,當Leader看到該節點為leaving狀態,會將其狀態修改為exiting,然後當所有節點看到該節點狀態為exiting,則Leader將該節點移除,狀態修改為removed狀態。
如果一個節點處於unreachable狀態,基於Gossip協議Leader是無法執行任何操作收斂(Convergence)到該節點的,所以unreachable狀態的節點的狀態是必須被改變的,它必須變成reachable狀態或者down狀態。如果該節點想再次加入到Akka集群,它必須需要重新啟動,並且重新加入集群(經由joining狀態)。

Persistence:Akka的持久性能夠使得有狀態的Actor實例保存它的內部狀態,在Actor重啟後能夠更快的進行恢復。需要強調的是,持久化的僅僅是Actor的內部狀態,而不是Actor當前的狀態,Actor內部狀態的變化會被一追加的方式存到到指定的存儲中,一旦追加完成存儲狀態,這些數據就不會被更新。有狀態的Actor通過重放(Replay)持久化的狀態來快速恢復,重建內部狀態。

Akka適用場景

Akka適用場景非常廣泛,這裏根據一些已有的使用案例來總結一下,Akka能夠在哪些應用場景下投入生產環境:

  • 事務處理(Transaction Processing) 在線遊戲系統、金融/銀行系統、交易系統、投註系統、社交媒體系統、電信服務系統。
  • 後端服務(Service Backend) 任何行業的任何類型的應用都可以使用,比如提供REST、SOAP等風格的服務,類似於一個服務總線,Akka支持縱向&橫向擴展,以及容錯/高可用(HA)的特性。
  • 並行計算(Concurrency/Parallelism) 任何具有並發/並行計算需求的行業,基於JVM的應用都可以使用,如使用編程語言Scala、Java、Groovy、JRuby開發。
  • 仿真

Master/Slave架構風格的計算系統、計算網格系統、MapReduce系統。

  • 通信Hub(Communications Hub)電信系統、Web媒體系統、手機媒體系統。
  • 復雜事件流處理(Complex Event Stream Processing)Akka本身提供的Actor就適合處理基於事件驅動的應用,所以可以更加容易處理具有復雜事件流的應用。

其它特性

Akka還支持很多其它特性,如下所示:

  • 支持Future,可以同步或異步地獲取發送消息的結果
  • 支持基於事件的Dispatcher,將多個Actor與一個線程池綁定
  • 支持消息路由,可以提供不同的消息路由策略,如Akka支持如下策略:RoundRobinRoutingLogic、RandomRoutingLogic、SmallestMailboxRoutingLogic、BroadcastRoutingLogic、ScatterGatherFirstCompletedRoutingLogic、TailChoppingRoutingLogic、ConsistentHashingRoutingLogic
  • 支持FSM,提供基於事件的狀態轉移

一 Akka學習 - actor