Akka是JAVA虛擬機(jī)平臺上構(gòu)建高并發(fā)、分布式和容錯應(yīng)用的工具包和運(yùn)行時。Akka用Scala語言編寫,同時提供了Scala和Java的開發(fā)接口。Akka處理并發(fā)的方法基于Actor模型,Actor之間通信的唯一機(jī)制就是消息傳遞。
Akka特點(diǎn):
對并發(fā)模型進(jìn)行了更高的抽象
是異步、非阻塞、高性能的事件驅(qū)動編程模型
是輕量級事件處理(1GB內(nèi)存可容納百萬級別個Actor)
它提供了一種稱為Actor的并發(fā)模型,其粒度比線程更小,你可以在系統(tǒng)中啟用大量的Actor。
它提供了一套容錯機(jī)制,允許在Actor出現(xiàn)異常時進(jìn)行一些恢復(fù)或重置操作。
Akka既可以在單機(jī)上構(gòu)建高并發(fā)程序,也可以在網(wǎng)絡(luò)中構(gòu)建分布式程序,并提供位置透明的Actor定位服務(wù)。
maven依賴:

Actor模型
在并發(fā)程序中線程是并發(fā)程序的基本執(zhí)行單元,但在Akka中執(zhí)行單元是Actor。
傳統(tǒng)并發(fā)程序是基于面向?qū)ο蟮姆椒?,通過對象的方法調(diào)用進(jìn)行信息傳遞,如果對象的方法修改對象本身的狀態(tài),在多線程下就可能出現(xiàn)對象狀態(tài)的不一致,此時就必須對方法調(diào)用進(jìn)行同步,而同步操作會犧牲性能。
在Actor模型中并不是通過Actor對象的某個方法來告訴Actor需要做什么,而是給Actor發(fā)送一條消息。當(dāng)一個Actor收到消息后,它有可能根據(jù)消息的內(nèi)容做出某些行為,如更改自身狀態(tài),此時這個狀態(tài)的更改是Actor自身進(jìn)行的,并非由外界干預(yù)進(jìn)行的。





第一行打印了HelloWorld Actor的路徑,它是系統(tǒng)內(nèi)第一個被創(chuàng)建的Actor。路徑為:akka://hello/user/helloworld。第一個hello表示ActorSystem的系統(tǒng)名稱,即構(gòu)造時第一個入?yún)?。user表示用戶Actor,所有的用戶Actor都會掛載在user路徑下。最后helloworld是這個Actor的名字。
第二行打印了Greeter?Actor的路徑,三、四行為Greeter中輸出的信息。
第五行表示系統(tǒng)遇到了一條消息投遞失敗,原因是HelloWorld將自身停止了,導(dǎo)致Greeter發(fā)送的信息無法成功投遞。
當(dāng)使用Actor進(jìn)行并發(fā)開發(fā)時,關(guān)注點(diǎn)已經(jīng)不在線程上了,線程調(diào)度已經(jīng)被Akka框架進(jìn)行封裝,只需關(guān)注Actor對象即可。Actor對象之間的通過顯示的消息發(fā)送來傳遞信息。
當(dāng)系統(tǒng)內(nèi)有多個Actor時,Akka會自動在線程池中選擇線程來執(zhí)行我們的Actor,不同的Actor可能會被同一個線程執(zhí)行或者一個Actor可能被不同的線程執(zhí)行。
注意:不要在一個Actor中執(zhí)行耗時的代碼,這樣可能會導(dǎo)致其他Actor的調(diào)度出現(xiàn)問題。
消息投遞
Akka應(yīng)用是由消息驅(qū)動的,消息是除Actor之外最重要的核心組件。在Actor之間傳遞的消息應(yīng)該滿足不變性,即不變模式,可變的消息無法高效的在并發(fā)環(huán)境中使用。在Akka中推薦使用不可變對象。在代碼中可以使用final字段聲明,在消息構(gòu)造完成后,就不能再發(fā)生改變了。
消息投遞策略:
至多一次投遞:此策略中每一條消息最多會被投遞一次,可能會偶爾出現(xiàn)投遞失敗的情況,從而導(dǎo)致消息丟失。此策略高性能。
至少一次投遞:此策略中每一條消息至少會被投遞一次,直至成功。在一些偶然的情況,接收者可能會收到重復(fù)消息,但消息不會丟失。此策略需要保存消息投遞的狀態(tài)并不斷重試。
精確投遞:所有消息保證被精確的投遞并成功接收一次,既不會丟失也不會重復(fù)。此策略成本最高且不易實(shí)現(xiàn)。
關(guān)于消息的可靠性:沒有必要在Akka層保證消息的可靠性,這樣做成本太高且無必要。消息可靠性應(yīng)該在應(yīng)用的業(yè)務(wù)層進(jìn)行保證,有時丟失一些消息是符合應(yīng)用要求的。
消息投遞的順序性:Akka可以保證在一定程度上的投遞順序性。如Actor A1向A2順序發(fā)送了M1、M2、M3三條消息,Actor A3想A2順序發(fā)送了M4、M5、M6三條消息,則系統(tǒng)可以保證:
如果M1無丟失,它一定先于M2、M3被A2收到。
如果M2無丟失,它一定先于M3被A2收到。
如果M4無丟失,它一定先于M5、M6被A2收到。
如果M5無丟失,它一定先于M6被A2收到。
對于A2來說,來自A1向A3的消息并沒有順序性保證。

另外這種消息投遞規(guī)則不具備可傳遞性,如下圖:

--參考文獻(xiàn)《實(shí)戰(zhàn)Java高并發(fā)程序設(shè)計》