Akka是一個(gè)構(gòu)建在JVM上沼填,基于Actor模型的的并發(fā)框架酌摇,為構(gòu)建伸縮性強(qiáng),有彈性的響應(yīng)式并發(fā)應(yīng)用提高更好的平臺(tái)姨伟。本文主要是個(gè)人對(duì)Akka的學(xué)習(xí)和應(yīng)用中的一些理解。
Actor模型
Akka的核心就是Actor豆励,所以不得不說Actor夺荒,Actor模型我通俗的舉個(gè)例子,假定現(xiàn)實(shí)中的兩個(gè)人良蒸,他們只知道對(duì)方的地址技扼,他們想要交流,給對(duì)方傳遞信息嫩痰,但是又沒有手機(jī)淮摔,電話,網(wǎng)絡(luò)之類的其他途徑始赎,所以他們之間只能用信件傳遞消息和橙,很像現(xiàn)實(shí)中的的郵政系統(tǒng),你要寄一封信造垛,只需根據(jù)地址把信投寄到相應(yīng)的信箱中魔招,具體它是如何幫你處理送達(dá)的,你就不需要了解了五辽,你也有可能收到收信人的回復(fù)办斑,這相當(dāng)于消息反饋。上述例子中的信件就相當(dāng)于Actor中的消息,Actor與Actor之間只能通過消息通信乡翅。當(dāng)然Actor模型比這要復(fù)雜的多鳞疲,這里主要是簡(jiǎn)潔的闡述一下Actor模型的概念。
Akka中Actors模型
對(duì)并發(fā)模型進(jìn)行了更高的抽象
異步蠕蚜、非阻塞尚洽、高性能的事件驅(qū)動(dòng)編程模型
輕量級(jí)事件處理(1GB內(nèi)存可容納百萬級(jí)別個(gè)Actor)
為什么Actor模型是一種處理并發(fā)問題的解決方案?
一開始我也不怎么理解靶累,腦子里的一貫思維是處理并發(fā)問題就是如何保證共享數(shù)據(jù)的一致性和正確性腺毫,為什么會(huì)有保持共享數(shù)據(jù)正確性這個(gè)問題呢?無非是我們的程序是多線程的挣柬,多個(gè)線程對(duì)同一個(gè)數(shù)據(jù)進(jìn)行修改潮酒,若不加同步條件,勢(shì)必會(huì)造成數(shù)據(jù)污染邪蛔。那么我們是不是可以轉(zhuǎn)換一下思維急黎,用單線程去處理相應(yīng)的請(qǐng)求,但是又有人會(huì)問了侧到,若是用單線程處理叁熔,那系統(tǒng)的性能又如何保證。Actor模型的出現(xiàn)解決了這個(gè)問題床牧。
Actor模型概圖
:
從上圖中我們可以看到荣回,Actor與Actor之前只能用消息進(jìn)行通信,當(dāng)某一個(gè)Actor給另外一個(gè)Actor發(fā)消息戈咳,消息是有順序的心软,你只需要將消息投寄的相應(yīng)的郵箱,至于對(duì)方Actor怎么處理你的消息你并不知道著蛙,當(dāng)然你也可等待它的回復(fù)删铃。
JVM中的Actor有以下幾個(gè)特點(diǎn):
每個(gè)Actor都有對(duì)應(yīng)一個(gè)郵箱
Actor是串行處理消息的
Actor中的消息是不可變的
其實(shí)只從上面一些描述來看,并不能看出Actor在處理并發(fā)問題上的有什么優(yōu)勢(shì)踏堡。
但我總結(jié)了兩點(diǎn):簡(jiǎn)化并發(fā)編程
猎唁,提升程序性能
1.簡(jiǎn)化并發(fā)編程:
我們一開始說過并發(fā)導(dǎo)致最大的問題就是對(duì)共享數(shù)據(jù)的操作,我們?cè)诿鎸?duì)并發(fā)問題時(shí)多采用的是
用鎖去保證共享數(shù)據(jù)的一致性顷蟆,但這同樣也會(huì)帶來其他相關(guān)問題诫隅,比如要去考慮鎖的粒度(對(duì)方法,程序塊等)帐偎,鎖的形式(讀鎖逐纬,寫鎖等)等問題,這些問題對(duì)并發(fā)程序來說是至關(guān)重要的削樊,但一個(gè)初寫并發(fā)程序的程序員來說豁生,往往不能掌控的很好兔毒,這無疑給程序員在編程上提高了復(fù)雜性,而且還不容易掌控甸箱,但使用Actor就不導(dǎo)致這些問題育叁,首先Actor的消息特性就覺得了在與Actor通信上不會(huì)有共享數(shù)據(jù)的困擾,另外在Actor內(nèi)部是串行處理消息的芍殖,同樣不會(huì)對(duì)Actor內(nèi)的數(shù)據(jù)造成污染豪嗽,用Actor編寫并發(fā)程序無疑大大降低了編碼的復(fù)雜度。
2.提升程序性能:
我們之前說過既然用單線程處理围小,那如何保證程序的性能昵骤?首先Actor是非常輕量級(jí)的树碱,你可以再程序中創(chuàng)建許多個(gè)Actor肯适,而且Actor是異步的,那么如何利用它的這個(gè)特性呢成榜,我們要做的就是把相應(yīng)的并發(fā)事件盡可能的分割成一個(gè)個(gè)小的事件框舔,讓每個(gè)Actor去處理相應(yīng)的小事件,充分去利用它異步的特點(diǎn),來提升程序的性能赎婚。
其實(shí)Scala中原生的Actor并不能完成很多事刘绣,不是一套完整的并發(fā)解決方案,不適合用于生產(chǎn)環(huán)境挣输,比如錯(cuò)誤恢復(fù)纬凤,狀態(tài)持久化等,所以在較新版本的Scala類庫中撩嚼,Akka包已經(jīng)取代了原生的Actor停士。
Akka
那下面我們來簡(jiǎn)單說說Akka吧,Akka作為一套成熟的并發(fā)解決方案完丽,已經(jīng)被業(yè)界大量采用恋技,尤其是在金融,游戲等領(lǐng)域逻族,Akka中的容錯(cuò)機(jī)制蜻底,持久化,遠(yuǎn)程調(diào)用聘鳞,日志等都是很重要的模塊薄辅,這些內(nèi)容都會(huì)在這個(gè)系列的后續(xù)文章里一一講解。下面就以一個(gè)入門Akka程序來結(jié)束本篇文章吧】倭В現(xiàn)在我們假設(shè)有一個(gè)家居機(jī)器人长搀,我們只需要給它發(fā)送消息它便會(huì)幫我們處理相應(yīng)的事情,現(xiàn)在我們用程序來模擬這個(gè)場(chǎng)景:源碼鏈接
本示例使用Scala語言鸡典,構(gòu)建工具為SBT源请,IDE為IntelliJ IDEA.
1.首先創(chuàng)建一個(gè)基于SBT的Scala工程
build.sbt
配置:
name := "Example_01"
version := "1.0"
scalaVersion := "2.11.8"
val akkaVersion = "2.4.16"
libraryDependencies +=
"com.typesafe.akka" %% "akka-actor" % akkaVersion
2.我們來定義一些消息:
trait Action{
val message: String
val time: Int
}
case class TurnOnLight(time: Int) extends Action { // 開燈消息
val message = "Turn on the living room light"
}
case class BoilWater(time: Int) extends Action { // 燒水消息
val message = "Burn a pot of water"
}
3.我們利用Actor來實(shí)現(xiàn)一個(gè)模擬機(jī)器人:
class RobotActor extends Actor {
val log = Logging(context.system, this)
def receive: Receive = { //機(jī)器人接受指令
case t: TurnOnLight => log.info(s"${t.message} after ${t.time} hour")
case b: BoilWater => log.info(s"${b.message} after ${b.time} hour")
case _ => log.info("I can not handle this message")
}
}
4.我們?nèi)y(cè)試這個(gè)機(jī)器人:
object Example_01 extends App {
val actorSyatem = ActorSystem("robot-system")
val robotActor = actorSyatem.actorOf(Props(new RobotActor()), "robotActor") //創(chuàng)建一個(gè)機(jī)器人
robotActor ! TurnOnLight(1) //給機(jī)器人發(fā)送一個(gè)開燈命令
robotActor ! BoilWater(2) //給機(jī)器人發(fā)送一個(gè)燒水命令
robotActor ! "who are you" //給機(jī)器人發(fā)送一個(gè)任意命令
actorSyatem terminate ()
}
5.運(yùn)行結(jié)果
[INFO] [03/19/2017 13:48:05.622] [robot-system-akka.actor.default-dispatcher-4] [akka://robot-system/user/robotActor] Turn on the living room light after 1 hour
[INFO] [03/19/2017 13:48:05.622] [robot-system-akka.actor.default-dispatcher-4] [akka://robot-system/user/robotActor] Burn a pot of water after 2 hour
[INFO] [03/19/2017 13:48:05.622] [robot-system-akka.actor.default-dispatcher-4] [akka://robot-system/user/robotActor] I can not handle this message
上面是一個(gè)非常簡(jiǎn)單的Akka例子,我們首先創(chuàng)建了一個(gè)機(jī)器人的Actor,然后通過向它發(fā)送不同指令谁尸,讓它根據(jù)指令去做相應(yīng)的事情舅踪,大家可以自己嘗試去寫一寫相似的例子。
這篇就先到這里了良蛮,下一篇主要給大家講講Akka中Actor的分層結(jié)構(gòu)抽碌。
文章允許轉(zhuǎn)載、使用决瞳,但需要保留文章署名 godpan.me,如有寫的不當(dāng)之處货徙,也歡迎大家指正,聯(lián)系郵箱:godpan.sen@gmail.com