Actor References, Paths and Addresses 20

原文:https://doc.akka.io/docs/akka/2.5/general/addressing.htmlhtml

在這裏描述瞭如何在可能分佈的actor系統中識別和定位actor。它與Actor系統造成內在監督層次結構以及Actor之間的通訊相對於它們在多個網絡節點上的放置是透明的中心思想聯繫在一塊兒。shell

上圖顯示了Actor系統中最重要的實體之間的關係,請繼續閱讀詳細信息。網絡

What is an Actor Reference?

actor reference是ActorRef的子類型,其最重要的目的是支持向它所表明的actor發送消息。每一個Actor均可以經過self字段訪問其(local)引用,包括對於發送給其餘actor的全部消息。在消息處理期間,actor能夠經過sender()方法訪問表示當前消息的發送者的引用。tcp

根據actor系統的配置,支持幾種不一樣類型的actor引用:工具

  • 純粹的本地actor引用由未配置爲支持網絡功能的actor系統使用。若是經過網絡鏈接發送到遠程JVM,這些actor引用將不起做用。
  • 啓用遠程處理時的本地actor引用由actor系統使用,該系統支持那些表示同一JVM中的actor的引用的網絡功能。爲了在發送到其餘網絡節點時也能夠訪問,這些引用包括協議和遠程尋址信息。
  • 存在用於路由器的本地Actor引用的子類型(即,在路由器特徵中混合的角色)。它的邏輯結構與前面提到的本地引用相同,可是向它們發送消息直接發送給它們的一個子節點。
  • 遠程actor引用表示使用遠程通訊可訪問的actor,即向它們發送消息將透明地序列化消息並將它們發送到遠程JVM。
  • 有幾種特殊類型的actor引用,其行爲相似於本地actor引用,用於全部實際目的:
  1. PromiseActorRef是Promise的特殊表示,目的是由Actor的響應完成。akka.pattern.ask建立此actor reference。
  2. DeadLetterActorRef是dead信服務的默認實現,Akka將全部目的地關閉或不存在的消息路由到該服務。
  3. EmptyLocalActorRef是Akka在查找不存在的本地actor路徑時返回的內容:它等同於DeadLetterActorRef,但它保留了它的路徑,以便Akka能夠經過網絡發送它並將其與該路徑的其餘現有actor引用進行比較,其中多是在Actor銷燬前得到的。
  • 而後有一些一次性的內部實現,可能你永遠不會真的可能啊到:
  1. 有一個Actor引用不表明一個Actor,但只是做爲根守護者的僞監督者,咱們稱之爲「the one who walks the bubbles of space-time」。
  2. 在實際啓動actor建立工具以前啓動的第一個日誌記錄服務是一個假的actor引用,它接受日誌事件並將它們直接打印到標準輸出;它是Logging.StandardOutLogger。

What is an Actor Path?

因爲Actor是以嚴格的分層方式建立的,所以存在一個獨特的Actor名稱序列,經過遞歸地跟隨子和父母之間的監督連接向下朝向Actor系統的根來給出。此序列能夠看做是文件系統中的文件夾,所以咱們採用名稱「path」來引用它,儘管actor層次結構與文件系統層次結構有一些根本區別。測試

一個actor路徑包含一個anchor,它標識了actor系統,而後是路徑元素的串聯,從根守護者到指定的actor;path元素是遍歷的actor的名稱,並用斜槓分隔。編碼

What is the Difference Between Actor Reference and Path?

actor reference指定一個actor,reference的生命週期與actor的生命週期相匹配;一個actor path表明一個名字,該名字多是也可能不是由Actor在的位置,並且path自己沒有生命週期,它永遠不會變得無效。您能夠在不建立actor的狀況下建立actor path,可是若是不建立相應的actor,則沒法建立actor reference。spa

您能夠建立一個actor,終止它,而後建立一個具備相同actor path的新actor。新建立的Actor是的新化身。這不是同一個Actor。對舊化身的Actor引用對新的化身無效。發送到舊actor 應用的消息即便具備相同的路徑,也不會被傳遞給新的化身。設計

Actor Path Anchors

每一個actor路徑都有一個地址組件,描述了能夠訪問相應actor的協議和位置,而後是從根目錄開始的層次結構中actor的名稱。例子是:3d

這裏,akka.tcp是2.4版本的默認遠程傳輸;其餘運輸工具是可插拔的。主機和端口部分的解釋(即示例中的host.example.com:5678)取決於所使用的傳輸機制,但它必須遵照URI結構規則。

Logical Actor Paths

經過遵循父監督連接到根監護人得到的惟一路徑稱爲logical actor path。此路徑與actor的建立祖先徹底匹配,所以只要設置了actor系統的遠程配置(以及路徑的地址組件),它就徹底肯定了。

Physical Actor Paths

雖然邏輯actor路徑描述了一個actor系統內的功能位置,可是基於配置的遠程部署意味着能夠在不一樣於其父節點的網絡主機上建立actor,即在不一樣的actor系統內。在這種狀況下,遵循來自根監護人的actor路徑須要遍歷網絡,這是一項代價高昂的操做。所以,每一個actor也有一個物理路徑,從實際actor對象所在的actor系統的根守護者開始。在查詢其餘actor時使用此路徑做爲發送方引用將容許它們直接回復此actor,從而最大限度地減小路由引發的延遲。

一個重要方面是物理actor路徑從不跨越多個actor系統或JVM。這意味着若是遠程監督其祖先之一,則演員的邏輯路徑(監督層級)和物理路徑(演員部署)可能會發散。

How are Actor References obtained?

如何得到actor引用有:經過建立actor或查找它們,後者的功能來自於從具體actor路徑建立actor引用和查詢邏輯actor層次結構的兩種方式。

Creating Actors

Actor系統一般是經過使用ActorSystem.actorOf方法在守護者actor下建立actor,而後在建立的actor中使用ActorContext.actorOf來生成actor樹來啓動的。這些方法返回對新建立的actor的引用。每一個Actor均可以直接訪問(經過其ActorContext)其父級,自身及其子級的引用。這些引用能夠在消息中發送給其餘Actor,使他們可以直接回復。

Looking up Actors by Concrete Path

 此外,可使用ActorSystem.actorSelection方法查找actor引用。該選擇能夠用於與所述Actor進行通訊,而且在傳送每一個消息時查找與該選擇相對應的Actor。

要獲取綁定到特定actor的生命週期的ActorRef,您須要向actor發送消息(例如內置Identify消息)並使用actor的回覆的sender()引用。

Absolute vs. Relative Paths

除了ActorSystem.actorSelection以外,還有ActorContext.actorSelection,它在任何actor中均可用做context.actorSelection。這會產生一個actor selection,就像它在ActorSystem上的雙胞胎同樣,但不是從actor樹的根開始查找路徑,而是從當前的actor開始。由兩個點(「..」)組成的路徑元素可用於訪問父actor。例如,您能夠向特定的兄弟發送消息:

也能夠一般的方式在上下文中查找絕對路徑,即

將按預期工做。

Querying the Logical Actor Hierarchy

因爲actor系統造成相似層次結構的文件系統,所以能夠採用與Unix shell支持的相同方式匹配路徑:您能夠用通配符(*«*»*和«?»)替換(部分)路徑元素名稱制定一個能夠匹配零個或多個實際Actor的選擇。由於結果不是單個actor引用,因此它具備不一樣類型的ActorSelection,而且不支持ActorRef執行的完整操做集。可使用ActorSystem.actorSelection和ActorContext.actorSelection方法制定選擇,並支持發送消息:

將msg發送給包括當前Actor在內的全部兄弟姐妹。對於使用actorSelection得到的引用,完成監督層次結構的遍歷以便執行消息發送。因爲與消息選擇匹配的確切Actor集可能會在消息進入收件人時發生變化,所以沒法觀看選擇的生動性變化。爲了作到這一點,經過發送請求並收集全部答案,提取發件人參考,而後觀察全部發現的具體Actor來解決不肯定性。在未來的版本中能夠改進這種解決選擇的方案。

Actor Reference and Path Equality

ActorRef的相等性與ActorRef對應於目標actor化身的意圖相匹配。當兩個actor引用具備相同的路徑並指向相同的actor化身時,它們相等。指向已終止的actor的引用不會比較指向具備相同路徑的另外一個(從新建立的)actor的引用。請注意,由失敗引發的actor的重啓仍然意味着它是相同的actor化身,即對於ActorRef的使用者不可見重啓。

若是您須要跟蹤集合中的actor引用而且不關心確切的actor化身,則可使用ActorPath做爲鍵,由於在比較actor路徑時不考慮目標actor的標識符。

Reusing Actor Paths

當Actor被終止時,它的引用將指向dead信郵箱,DeathWatch將發佈其最後的過渡,而且一般不會再次恢復生命(由於Actor生命週期不容許這樣)。雖然有可能在之後建立一個具備相同路徑的actor ,因爲在不保持全部可用的actor的集合可用的狀況下沒法強制執行相反的操做。

在很是具體的狀況下作這件事多是正確的,但要確保將這個處理精確地限制在Actor的主管,由於這是惟一能夠可靠地檢測到名稱的正確註銷的Actor,在此以前建立新的孩子會失敗。 

在測試期間,當測試對象依賴於在特定路徑上實例化時,也可能須要它。在這種狀況下,最好模擬其主管,以便它將Terminated消息轉發到測試過程當中的適當點,使後者可以等待正確的名稱註銷。

The Interplay with Remote Deployment

當actor建立子節點時,actor系統的部署者將決定新actor是在同一個JVM中仍是在另外一個節點上。在第二種狀況下,Actor的建立將經過網絡鏈接觸發,以在不一樣的JVM中發生,從而在不一樣的Actor系統中發生。遠程系統將新actor放置在爲此目的保留的特殊路徑下方,新actor的主管將是遠程actor引用(表示觸發其建立的actor)。在這種狀況下,context.parent(supervisor引用)和context.path.parent(actor的路徑中的父節點)不表明同一個actor。可是,在主管中查找孩子的名字會在遠程節點上找到它,保留邏輯結構,例如發送到未解析的actor引用時。

What is the Address part used for?

經過網絡發送actor引用時,它由其路徑表示。所以,該路徑必須徹底編碼將消息發送給底層Actor所需的全部信息。這是經過在路徑字符串的地址部分中編碼協議,主機和端口來實現的。當actor系統從遠程節點接收actor路徑時,它會檢查該路徑的地址是否與該actor系統的地址匹配,在這種狀況下,它將被解析爲actor的本地引用。不然,它將由遠程actor引用表示。

Top-Level Scopes for Actor Paths

路徑層次結構的根目錄是根守護者,在該守護者之上找到全部其餘actor;它的名字是 」/」。下一級包括如下內容:

  • 「/ user」是全部用戶建立的頂級Actor的守護者;使用ActorSystem.actorOf建立的actor位於此下方。
  • 「/ system」是全部系統建立的頂級Actor的守護者,例如記錄在actor系統開始時由配置自動部署的偵聽器或actor。
  • 「/ deadLetters」是dead letter actor,它是發送給已中止或不存在的actor的全部消息被從新路由的地方(盡力而爲:即便在本地JVM中也可能丟失消息)。
  • 「/ temp」是全部系統建立的臨時Actor的守護者,例如:那些在ActorRef.ask的實現中使用的。
  • 「/ remote」是一我的爲路徑,全部其主管是遠程參與者的Actor都在其下面。

爲這樣的Actor構建命名空間的須要源於一箇中心且很是簡單的設計目標:層次結構中的全部東西都是Actor,全部Actor都以相同的方式運做。所以,您不只能夠查找您建立的Actor,還能夠查找系統監護人並向其發送消息(在這種狀況下,它將盡職盡責地丟棄)。這個強大的原則意味着沒有要記住的怪癖,它使整個系統更加統一和一致。

若是您想了解有關Actor系統頂層結構的更多信息,請查看The Top-Level Supervisors

原文:https://doc.akka.io/docs/akka/2.5/general/addressing.html

未完待續!

相關文章
相關標籤/搜索