當前位置:
首頁 > 最新 > 分散式編程-Akka介紹與應用

分散式編程-Akka介紹與應用

Akka介紹

Akka是用scala編寫的actor模型框架。它在使用中不需要鎖和多線程,每個Actor在獨立空間中進行數據操作,Actor之間並不直接通信,而是通過了消息來相互溝通,每一個Actor都把它要做的事情都封裝在了它的內部,操作都是非同步進行的。理論上來講,每一個Actor都擁有屬於自己的輕量級線程,保護它不會被系統中的其他部分影響.因此,我們在編寫Actor時,就不用擔心並發的問題, 通過Actor能夠簡化鎖以及線程管理.它可以用於高並發、分散式場景,需要注意的是,Akka消息的傳遞不保證絕對可靠投遞,當然這帶來了好處是整個實現簡單.

Actor具有以下的特性

提供了一種高級的抽象,能夠封裝狀態和操作.簡化並發應用的開發.

提供了非同步的非阻塞的/高性能的事件驅動模型

超級輕量級的線程事件處理能力.

相關文檔: http://blog.csdn.net/jmppok/article/details/17264495


在了解Akka前先了解幾個概念

並發&並行

並發: 指的是兩個或多個任務都有進展,即使他們沒有被同時執行。例如可以這樣實現:劃分出時間片,幾個任務交叉執行,儘管時間片的執行是線性的。並行: 指可以真正同時執行。

非同步&同步

所謂同步,就是在發出一個功能調用時,在沒有得到結果之前,該調用就不返回。當一個非同步過程調用發出後,調用者不能立刻得到結果。實際處理這個調用的部件在完成後,通過狀態、通知和回調來通知調用者。

阻塞&非阻塞

阻塞調用是指調用結果返回之前,當前線程會被掛起。函數只有在得到結果之後才會返回。有人也許會把阻塞調用和同步調用等同起來,實際上他是不同的。對於同步調用來說,很多時候當前線程還是激活的,只是從邏輯上當前函數沒有返回而已。非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回


akka-actor:最核心的依賴包,裡面實現了Actor模型的大部分東西

akka-agent:代理/整合了Scala中的一些STM特性

akka-camel:整合了Apache的Camel

akka-cluster:akka集群依賴,封裝了集群成員的管理和路由

akka-kernel:akka的一個極簡化的應用伺服器,可以脫離項目單獨運行.

akka-osgi:對OSGI容器的支持,有akka的最基本的Bundle

akka-remote:akka遠程調用

akka-slf4j:Akka的日誌事件監聽

akka-testkit:Akka的各種測試工具

akka-zeromq:整合ZeroMQ

其中最總要的就是akka-actor,最簡單的AKKA使用的話,只需要引入這個包就可以了.

建立角色系統,ActorSystem;

定義角色,actor;

註冊角色,actorSystem.actorOf;

消息的傳遞,tell;

在actor內消息的處理(處理完後,也可通過actorSelect路徑選擇其它actor,並發送消息)

相關模塊說明

角色系統

在akka中,所有角色都需在角色系統中,可以通過ActorSystem.create方法建立,同時可以指定角色系統名稱,這會在actor路徑中體現出來;

角色(Actor)

通過繼承AbstractActor類,實現抽象方法createReceive,並在此方法定義消息處理模塊(使用reciveBuilder.build進行構造), 接收消息(消息類型,其實也就是消息的class類型區分消息),並進行消息處理;

角色(Actor)註冊/創建

通過ActorSystem的actorOf方法創建actor,創建時可以通過new BalancingPool(3)指定該actor的工作worker數量,以及actor的名稱,這會在路徑中體現出來。

角色(Actor)路徑及查找

Akka內的各個actor採用類似於分散式文件系統(如hdfs)進行管理,actor類似於文件系統的各個文件。

Akka主要根路徑有三個:/(根路徑),/system(系統相關的路徑),/user(用戶路徑,通常定義的actor在此路徑下)。

有了路徑,可以通過getContext().actorSelect()方法基於路徑,獲取到相關actor引用,進而發送消息.

/user: 守護Actor

這個名為"/user"的守護者,作為所有用戶創建actor的父actor,可能是需要打交道最多的。使用system.actorOf()創建的actor都是其子actor。這意味著,當該守護者終止時,系統中所有的普通actor都將被關閉。同時也意味著,該守護者的監管策略決定了普通頂級actor是如何被監督的.

/system: 系統守護者

這個特殊的守護者被引入,是為了實現正確的關閉順序,即日誌(logging)要保持可用直到所有普通actor終止,即使日誌本身也是用actor實現的。其實現方法是:系統守護者觀察user守護者,並在收到Terminated消息初始化其自己的關閉過程。頂級的系統actor被監管的策略是,對收到的除ActorInitializationException和ActorKilledException之外的所有Exception無限地執行重啟,這也將終止其所有子actor。所有其他Throwable被上升,然後將導致整個actor系統的關閉。

/: 根守護者

根守護者所謂「頂級」actor的祖父,它監督所有在Actor路徑的頂級作用域中定義的特殊actor,使用發現任何Exception就終止子actor的SupervisorStrategy.stoppingStrategy策略。其他所有Throwable都會被上升……但是上升給誰?所有的真實actor都有一個監管者,但是根守護者沒有父actor,因為它就是整個樹結構的根。因此這裡使用一個虛擬的ActorRef,在發現問題後立即停掉其子actor,並在根守護者完全終止之後(所有子actor遞歸停止),立即把actor系統的isTerminated置為true。


Akka中有兩種類型的監管策略:OneForOneStrategy 和AllForOneStrategy.

兩者都配置有從異常類型監管指令間的映射(見上文),並限制了一個孩子被終止之前允許失敗的次數。它們之間的區別在於,前者只將所獲得的指令應用在發生故障的子actor上,而後者則是應用在所有孩子上。通常情況下,你應該使用OneForOneStrategy,這也是默認的策略。


有三種基本類型:

至多一次投遞的意思是對該機制下的每條消息,會被投遞0或1次;更隨意的說法就是,它意味著消息可能會丟失。

至少一次投遞的意思對該機制下的每條消息,有可能為投遞進行多次嘗試,以使得至少有一個成功;更隨意的說法就是,消息可能重複,但不會丟失。

恰好一次投遞的意思對該機制下的每條消息,接收者會正好得到一次投遞;消息既不能丟,也不會重複。

第一種是最廉價的——性能最高,實現開銷最少——因為它可以用打後不管(fire-and-forget)的方式完成,不需要在發送端或傳輸機制中保留狀態。第二種方式要求重試來對抗傳輸丟失,這意味著需要在發送端保持狀態,並在接收端使用確認機制。第三種是最昂貴的——並因此表現最差——因為除了需要第二種方式的機制以外,還需要在接收端保持狀態,以過濾重複的投遞.

Maven依賴

定義Actor

程序主類

程序解讀

創建一個Actor系統,命名為"helloSystem"

每個Actor對外封閉,使用ActorRef的actorOf方法創建Actor,示例創建了一個名為"helloActor"的Actor,綁定HelloActor事件處理.

發送消息給"helloActor",tell()方法是非同步的,它只給Actor的郵箱放一封郵件,然後就返回了。tell()方法的第一個參數是消息,第二個參數是發送者,這樣接收者Actor就知道是誰給自己發的消息了. 示例中在主方法中發送消息,所以首次消息發送者為 .

執行輸出

示例使用Akka實現一個MapReduce的經典示例

Maven依賴

工程結構

消息定義

Actor定義

定義

定義

定義

定義

測試主類定義

執行輸出


https://doc.yonyoucloud.com/doc/akka-doc-cn/2.3.6/scala/book/chapter1/introduction.html

歡迎分享、關注【異次猿】!!!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 異次猿 的精彩文章:

TAG:異次猿 |