Akka入門實例

Akka 是一個用 Scala 編寫的庫,用於簡化編寫容錯的、高可伸縮性的 Java 和 Scala 的 Actor 模型應用。web

Actor模型並不是什麼新鮮事物,它由Carl Hewitt於上世紀70年代早期提出,目的是爲了解決分佈式編程中一系列的編程問題。其特色以下:編程

  • 系統中的全部事物均可以扮演一個Actor
  • Actor之間徹底獨立
  • 在收到消息時Actor所採起的全部動做都是並行的,在一個方法中的動做沒有明確的順序
  • Actor由標識和當前行爲描述
  • Actor可能被分紅原始(primitive)和非原始(non primitive)類別
  • 非原始Actor有
    • 由一個郵件地址表示的標識
    • 當前行爲由一組知識(acquaintances)(實例變量或本地狀態)和定義Actor在收到消息時將採起的動做組成
  • 消息傳遞是非阻塞和異步的,其機制是郵件隊列(mail-queue)
  • 全部消息發送都是並行的

首先經過一個簡單的例子快速簡單的介紹AKKA actor 是如何實現和使用的。網絡

建立簡單的 Actor 模式應用程序,定義EchoServer以下代碼所示,EchoServer類繼承 AKKA 中的 Actor 類,定義偏函數(Partial Function)receive,receive 函數中經過模式匹配(Pattern Match)實現程序邏輯。異步

 

 1 package foo  2 
 3 import akka.actor.{ Actor, ActorSystem, Props}  4 import akka.event.Logging  5 
 6 object test extends App {  7     
 8 val system = ActorSystem()  9 
10 class EchoServer extends Actor { 11   val log = Logging(context.system,this) 12   def receive = { 13      case msg: String => println("echo " + msg) 14  } 15 } 16 
17 val echoServer = system.actorOf(Props[EchoServer]) 18 echoServer ! "hello!"

如上代碼所示,經過 AKKA 中的 ActorSystem 對象的 actorOf 方法建立上面的 EchoServer類對象實例,返回AKKA 中的 ActorRef 類型的 EchoServer對象, echoServer對象是 EchoServer類對象實例的引用,經過 echoServer對象能夠向 EchoServer類對象實例發送消息。分佈式

注意: 函數

  •  若是 receive 方函數中不存在默認匹配,則會向 ActorSystem 的事件消息流(Event Stream)發送akka.actor.UnhandledMessage(message,sender,recipient)消息。 
  •  ActorRef 類型的對象是不可變的和可序列化的,能夠在網絡中進行傳輸,做爲遠程對象使用,具體的操做仍是在本地的 Actor 類對象。
  •  Actor 對象的名稱能夠在建立時省略;若是不省略 actor 對象的名稱,那麼在同一個父 actor 對象下子actor 的名稱必須惟一。 
  • Actor 對象的名稱不能爲空,而且不能是以‘$’開頭的字符串。

建立帶參數構造器 Actor this

 

 1 package foo  2 
 3 import akka.actor.{ Actor, ActorSystem, Props}  4 import akka.event.Logging  5 
 6 object test extends App {  7     
 8 val system = ActorSystem()  9 
10 class Actor2(name:String) extends Actor { 11   val log = Logging(context.system,this) 12   def receive = { 13     case "hello" => log.info(name + " echo hello " ) 14     case _ => log.info(name + " unknown msg") 15  } 16 } 17 val actor2 = system.actorOf(Props(new Actor2("tom"))) 18 
19 actor2 ! "hello"

如上面代碼所示,Actor2 類帶有參數的構造函數,這種狀況下沒法使用Props[Actor2]的方式建立 actor2 對象。能夠採用 call-by-name塊(參考scala相關內容)的方式建立 actor2 對象spa

注意: 線程

  • Props(...)中不能始終傳入同一個 actor 對象,例如 val lazy 或 object extends Actor 等單例工廠實現方式,這會和 AKKA 中 actor restart 機制衝突。 
  •  構造器參數不能是可變的(var),由於 call-by-name 塊可能被其它線程調用,引發條件競爭。

Actor API
Actor trait 只定義了一個抽象方法,就是上面提到的 receive, 用來實現actor的行爲。scala

若是當前 actor 的行爲與收到的消息不匹配,則會調用 unhandled, 它的缺省實現是向actor系統的事件流中發佈一條 akka.actor.UnhandledMessage(message, sender, recipient)。

另外,它還包括:

  • self 表明本actor的 ActorRef
  • sender 表明最近收到的消息的發送actor,一般用於下面將講到的 迴應消息中
  • supervisorStrategy 用戶可重寫它來定義對子actor的監管策略
  • context 暴露actor和當前消息的上下文信息
相關文章
相關標籤/搜索