Akka是一個構建在JVM上,基於Actor模型的的併發框架,爲構建伸縮性強,有彈性的響應式併發應用提升更好的平臺。本文主要是我的對Akka的學習和應用中的一些理解。git
Akka的核心就是Actor,因此不得不說Actor,Actor模型我通俗的舉個例子,假定現實中的兩我的,他們只知道對方的地址,他們想要交流,給對方傳遞信息,可是又沒有手機,電話,網絡之類的其餘途徑,因此他們之間只能用信件傳遞消息,很像現實中的的郵政系統,你要寄一封信,只需根據地址把信投寄到相應的信箱中,具體它是如何幫你處理送達的,你就不須要了解了,你也有可能收到收信人的回覆,這至關於消息反饋。上述例子中的信件就至關於Actor中的消息,Actor與Actor之間只能經過消息通訊。固然Actor模型比這要複雜的多,這裏主要是簡潔的闡述一下Actor模型的概念。程序員
對併發模型進行了更高的抽象github
異步、非阻塞、高性能的事件驅動編程模型編程
輕量級事件處理(1GB內存可容納百萬級別個Actor)網絡
爲何Actor模型是一種處理併發問題的解決方案?多線程
一開始我也不怎麼理解,腦子裏的一向思惟是處理併發問題就是如何保證共享數據的一致性和正確性,爲何會有保持共享數據正確性這個問題呢?無非是咱們的程序是多線程的,多個線程對同一個數據進行修改,若不加同步條件,勢必會形成數據污染。那麼咱們是否是能夠轉換一下思惟,用單線程去處理相應的請求,可是又有人會問了,如果用單線程處理,那系統的性能又如何保證。Actor模型的出現解決了這個問題。併發
Actor模型概圖:框架
從上圖中咱們能夠看到,Actor與Actor以前只能用消息進行通訊,當某一個Actor給另一個Actor發消息,消息是有順序的,你只須要將消息投寄的相應的郵箱,至於對方Actor怎麼處理你的消息你並不知道,固然你也可等待它的回覆。異步
JVM中的Actor有如下幾個特色:工具
每一個Actor都有對應一個郵箱
Actor是串行處理消息的
Actor中的消息是不可變的
其實只從上面一些描述來看,並不能看出Actor在處理併發問題上的有什麼優點。
但我總結了兩點:簡化併發編程,提高程序性能
咱們一開始說過併發致使最大的問題就是對共享數據的操做,咱們在面對併發問題時多采用的是
用鎖去保證共享數據的一致性,但這一樣也會帶來其餘相關問題,好比要去考慮鎖的粒度(對方法,程序塊等),鎖的形式(讀鎖,寫鎖等)等問題,這些問題對併發程序來講是相當重要的,但一個初寫併發程序的程序員來講,每每不能掌控的很好,這無疑給程序員在編程上提升了複雜性,並且還不容易掌控,但使用Actor就不致使這些問題,首先Actor的消息特性就以爲了在與Actor通訊上不會有共享數據的困擾,另外在Actor內部是串行處理消息的,一樣不會對Actor內的數據形成污染,用Actor編寫併發程序無疑大大下降了編碼的複雜度。
咱們以前說過既然用單線程處理,那如何保證程序的性能?首先Actor是很是輕量級的,你能夠再程序中建立許多個Actor,並且Actor是異步的,那麼如何利用它的這個特性呢,咱們要作的就是把相應的併發事件儘量的分割成一個個小的事件,讓每一個Actor去處理相應的小事件,充分去利用它異步的特色,來提高程序的性能。
其實Scala中原生的Actor並不能完成不少事,不是一套完整的併發解決方案,不適合用於生產環境,好比錯誤恢復,狀態持久化等,因此在較新版本的Scala類庫中,Akka包已經取代了原生的Actor。
那下面咱們來簡單說說Akka吧,Akka做爲一套成熟的併發解決方案,已經被業界大量採用,尤爲是在金融,遊戲等領域,Akka中的容錯機制,持久化,遠程調用,日誌等都是很重要的模塊,這些內容都會在這個系列的後續文章裏一一講解。下面就以一個入門Akka程序來結束本篇文章吧。如今咱們假設有一個家居機器人,咱們只須要給它發送消息它便會幫咱們處理相應的事情,如今咱們用程序來模擬這個場景:源碼連接
本示例使用Scala語言,構建工具爲SBT,IDE爲IntelliJ IDEA.
1.首先建立一個基於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來實現一個模擬機器人:
class RobotActor extends Actor { val log = Logging(context.system, this) def receive: Receive = { //機器人接受指令 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.咱們去測試這個機器人:
object Example_01 extends App { val actorSyatem = ActorSystem("robot-system") val robotActor = actorSyatem.actorOf(Props(new RobotActor()), "robotActor") //建立一個機器人 robotActor ! TurnOnLight(1) //給機器人發送一個開燈命令 robotActor ! BoilWater(2) //給機器人發送一個燒水命令 robotActor ! "who are you" //給機器人發送一個任意命令 actorSyatem terminate () }
5.運行結果
[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
上面是一個很是簡單的Akka例子,咱們首先建立了一個機器人的Actor,而後經過向它發送不一樣指令,讓它根據指令去作相應的事情,你們能夠本身嘗試去寫一寫類似的例子。
這篇就先到這裏了,下一篇主要給你們講講Akka中Actor的分層結構。有興趣的同窗也能夠關注個人我的博客