閱讀875 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Akka學習筆記(二):Actor Systems


Akka學習筆記(二):Actor Systems


圖中表示的是一個Actor System,它顯示了在這個Actor System中最重要實體之間的關係。


什麼是actor,是一個封裝了狀態和行為的對象,每個actor都通過message交流,從自己的mailbox中讀取別的actor發送的消息。

注意
ActorSystem是重量級的對象,會創建1...N個線程,所以一個application一個ActorSystem。

層次結構

假設有一個actor,它的一個功能過於複雜,為了降低複雜度,可以將這個功能劃分成多個更小粒度的,更易管理的子任務,啟動新的child actors,監控它們任務運行(關於監控,詳見here)。每一個actor的創建者,也是其監控者。

設計一個actor system,我們要正確規劃,哪一個actor負責監控,監控什麼。幾點建議如下:

  • 負責分發工作的actor,管理接受任務的actor,因為包工頭知道所有任務出錯了該怎麼解決 :)
  • 擁有重要數據的actor,找出所有可能丟失該數據的子actor,監控,並處理它們的錯誤。類似Erlang的Error Kernel Pattern。(這段看不太明白)
  • 如果一個actor需要其他的actor傳遞其需求或職責,必將監控之。它應該查看其他actor的存活狀態,已經是否完成完成任務,當然這不是監控範疇了,不涉及到監控策略

以上僅做參考 -..-,總有例外

Actor Path

可以認為Actor Path是通過字符串對Actor層級關係進行組合用以標識唯一Actor的一種方式。我們在創建Actor Path時,不用創建Actor;但如果沒有創建對應的Actor,則不能創建Actor Reference。還可以創建一個Actor,再終止它,然後再以相同的Actor Path再創建一個新的Actor。新創建的Actor是Actor的新化身(Incarnation),但與舊的Actor並不是同一個。對於這個新化身而言,持有舊Actor的Actor Reference並不是有效的。消息發送給舊的Actor Reference,但不會被傳遞給新化身,即使它們具有相同的路徑。

Actor Path包含協議、位置和actor的層級。如下是一些Actor Path的實例:

//purely local
"akka://my-sys/user/service-a/worker1"                   

// remote"akka.tcp://my-sys@host.example.com:5678/user/service-b" 

//clustered (Future Extension)"cluster://my-cluster/service-c"

有兩種方式可以獲得Actor Reference:創建Actor或查找。

要創建Actor,可以調用ActorSystem.actorOf(),它創建的Actor在guardian actor之下;接著可以調用ActorContext.actorOf()在剛才創建的Actor內生成Actor樹。這些方法會返回新創建的Actor的引用。每個Actor都可以直接訪問Actor Context來或得它自身、Parent以及所有Children的引用。

要查找Actor Reference,則可調用ActorSystem.actorSelection()方法。要獲得限定到特定Actor的生命周期中的ActorRef,可以使用sender引用來發送一條消息如內建的Identity消息給Actor。

在查找ActorRef時,可以使用絕對路徑或相對路徑。如果是相對路徑,可以用兩個點(..)表示parent actor。例如:

context.actorSelection("../brother") ! msg

使用絕對路徑的例子:

context.actorSelection("/user/ServiceA") ! msg

還可以使用通配符查詢邏輯的Actor層級,例如下麵的例子就是發送消息給除當前Actor之外的所有同級Actor(因為..代表parent,所以這裏就意味找當前Actor的parent的下級Actor):

context.actorSelection("../*") ! msg

區別:actorOf vs. actorSelection vs. actorFor

  • actorOf:創建一個新的Actor。創建的Actor為調用該方法時所屬的Context下的直接子Actor;
  • actorSelection:當消息傳遞來時,隻查找現有的Actor,而不會創建新的Actor;在創建了selection時,也不會驗證目標Actors是否存在;
  • actorFor(已經被actorSelection所deprecated):隻會查找現有的Actor,而不會創建新的Actor。

遠程部署的相互影響

當一個Actor創建一個Child時,Actor的係統部署器會決定這個新的Actor究竟屬於同一個JVM,還是另一個節點。如果是後一種情況,Actor的創建就會通過在不同JVM的網絡連接而觸發,這屬於不同的Actor係統。遠程係統會將新的Actor放在一個特定的路徑下,且新Actor的Supervisor應該是一個遠程的Actor引用。而且,context.parent(Supervisor的引用)與context.path.parent(actor path的父節點)表示的不是同一個Actor。如下圖所示:

注意圖中展現的兩個不同的Actor係統之間的Route關係。在左邊的Actor係統中,Child Actor屬於Remote ActorRef,它指向了右邊遠端Actor係統中的一個Actor節點,該Actor對於右邊的Actor係統而言,屬於Local ActorRef,但它的Parent Actor卻是一個Remote ActorRef,它指向了左邊對應的Local ActorRef。

Actor Path的Top-Level Scopes

Actor路徑的根為”/”,而後續層級包括:”/user”, “/system”, “deadLetters”, “/temp”, “/remote”。

這裏體現了Akka遵循“簡單”原則的設計目標:層級中的任何事物都是Actor,且所有Actor的功能都采用同樣的方式。

Actor最佳實踐

  1. actors盡量不要阻塞
  2. actors間不要傳遞可變對象
  3. actor的state,behavior作為可變對象,是不能在actors中傳遞
  4. Top-level actors盡量少創建(沒看懂 T T)

阻塞需要謹慎管理

很多種情況,需要重新細看,分析

我們不需要關心什麼

actor會自動管理我們分配的固定資源。一個actor system可能有上百萬個actors,畢竟actor是非常輕量級的,每個實例隻占300字節。


最後更新:2017-04-03 05:39:34

  上一篇:go 網頁搜索之後的APP搜索
  下一篇:go Cocos2d-x開發實例:單點觸摸事件