Akka與裝置組一起工作《twelve》譯
Dependency
在專案中新增以下依賴項:
介紹:
讓我們仔細看看我們的用例所需的主要功能,在用於監控家庭溫度的完整物聯網系統中,將裝置感測器連線到我們系統的步驟可能如下所示:
- 家中的感測器裝置通過某種協議連線。
- 管理網路連線的元件接受連線。
- 感測器提供其組和裝置ID以向我們系統的裝置管理器元件註冊。
- 裝置管理器元件通過查詢或建立負責保持感測器狀態的actor來處理註冊。
- Actor迴應一個確認,暴露其ActorRef。
- 網路元件現在使用ActorRef進行感測器和裝置actor之間的通訊,而無需通過裝置管理器。
步驟1和2發生在我們的教程的範圍之外。在本章中,我們將開始解決步驟3-6,併為感測器建立一種方式來註冊我們的系統並與Actor進行通訊。但首先,我們還有另一個架構決策 - 我們應該使用多少級別的Actor來代表裝置組和裝置感測器?
Akka程式設計師面臨的主要設計挑戰之一是為Actor選擇最佳粒度。實際上,根據Actor之間互動的特徵,通常有幾種有效的方法來組織系統。例如,在我們的用例中,可以讓一個Actor維護所有組和裝置 - 可能使用雜湊對映。為每個組建立一個跟蹤同一家庭中所有裝置狀態的參與者也是合理的。
以下指南幫助我們選擇最合適的actor層次結構:
- 通常,更喜歡先引入大的粒度,比需要的更細粒度的Actor會導致比解決的更多的問題。
- 在系統需要時新增更精細的粒度:
- 更高的併發性。
- 具有許多狀態的Actor之間的複雜對話,我們將在下一章中看到一個很好的例子。
- 足夠的狀態,分成較小的角色是有意義的。
- 多個不相關的責任,使用單獨的參與者可以使個人失敗並恢復,而對他人的影響很小。
裝置管理層次結構
考慮到上一節中概述的原則,我們將裝置管理器元件建模為具有三個級別的Actor樹:
- 頂級管理員Actor代表裝置的系統元件。它也是查詢和建立裝置組和裝置角色的入口點。
- 在下一級別,組成員每個監督一個組ID(例如一個家庭)的裝置角色。它們還提供服務,例如查詢其組中所有可用裝置的溫度讀數。
- 裝置Actor管理與實際裝置感測器的所有互動,例如儲存溫度讀數。
出於以下原因,我們選擇了這種三層架構:
擁有各個Actor的組:
- 隔離組中發生的故障。如果單個actor管理所有裝置組,則導致重新啟動的一個組中的錯誤將消除否則無故障的組的狀態。
- 簡化查詢屬於組的所有裝置的問題。每個組actor僅包含與其組相關的狀態。
- 增加系統的並行性。由於每個組都有一個專用的actor,它們可以同時執行,我們可以同時查詢多個組。
將感測器建模為單個裝置角色:
- 將一個裝置actor的故障與組中的其餘裝置隔離。
- 增加收集溫度讀數的並行度。來自不同感測器的網路連線直接與其各個裝置Actor通訊,從而減少了爭用點。
通過定義架構,我們可以開始使用協議來註冊感測器。
註冊協議
作為第一步,我們需要設計協議以註冊裝置和建立將負責它的組和裝置Actor。此協議將由DeviceManager元件本身提供,因為它是唯一已知且可預先使用的Actor:按需建立裝置組和裝置Actor。
更詳細地檢視註冊,我們可以概述必要的功能:
- 當DeviceManager收到包含組和裝置ID的請求時:
- 如果經理已經擁有裝置組的參與者,它會將請求轉發給它。
- 否則,它會建立一個新的裝置組Actor,然後轉發該請求。
- DeviceGroup Actor接收註冊給定裝置的actor的請求:
- 如果組已經有裝置的actor,則組actor將請求轉發給裝置actor。
- 否則,DeviceGroup Actor首先建立一個裝置Actor,然後轉發該請求。
- 裝置參與者接收請求並向原始傳送者傳送確認。由於裝置actor確認收到(而不是組actor),感測器現在將使用ActorRef將訊息直接傳送給其actor。
我們將用於傳達註冊請求及其確認的訊息有一個簡單的定義:
在這種情況下,我們沒有在訊息中包含請求ID欄位。由於註冊發生一次,當元件將系統連線到某個網路協議時,ID並不重要。但是,通常最佳做法是包含請求ID。
現在,我們將從下往上開始實施協議。在實踐中,自上而下和自下而上的方法都可以工作,但在我們的情況下,我們從自下而上的方法中受益,因為它允許我們立即編寫新功能的測試,而不會模擬我們需要的部分後來建造。
向裝置角色添加註冊支援
我們層次結構的底部是Device actors。他們在註冊過程中的工作很簡單:回覆註冊請求並向發件人傳送確認。謹慎地對針對不匹配的組或裝置ID的請求新增安全措施。
我們假設註冊訊息的傳送者的ID保留在上層。我們將在下一部分向您展示如何實現這一目標。
裝置actor註冊碼如下所示:
我們現在可以編寫兩個新的測試用例,一個執行成功註冊,另一個測試ID不匹配的情況:
我們使用了TestKit中的expectNoMsg()輔助方法。此斷言將一直等到定義的時間限制,如果在此期間收到任何訊息,則會失敗。如果在等待期間沒有收到訊息,則斷言通過。保持這些超時較低(但不能太低)通常是一個好主意,因為它們會增加大量的測試執行時間。
下節再續!
原文:https://doc.akka.io/docs/akka/2.5/guide/tutorial_4.html
有什麼討論的內容,可以加我公眾號: