Akka和Actor一塊兒工做的消息《ten》譯

Dependencyhtml

在項目中添加如下依賴項:數據庫

Introduction

    在前面的主題解說中,咱們解釋瞭如何構建大型的Actor系統,即如何表示組件,如何在層次結構中排列Actor。在這一部分中,咱們將經過實現設備Actor來查看。編程

    若是咱們使用對象,咱們一般會將API設計爲接口,這是由實際實現填充的抽象方法的集合。在Actor的世界中,協議取代了接口。雖然不可能在編程語言中形式化通用協議,但咱們能夠編寫它們最基本的元素,即消息。所以,咱們將首先肯定要發送給設備Actor的消息。安全

    一般,消息屬於類別或模式。經過識別這些模式,您會發如今它們之間進行選擇並實現它們變得更加容易。第一個示例演示了請求 - 響應消息模式。網絡

識別設備的消息框架

    設備Actor的任務很簡單:編程語言

  • 收集溫度測量值
  • 請求時,報告最後測量的溫度

    可是,設備可能在沒有當即進行溫度測量的狀況下啓動。所以,咱們須要考慮溫度不存在的狀況。這也容許咱們在沒有寫入部分的狀況下測試Actor的查詢部分,由於設備Actor能夠報告空結果。分佈式

    用於從設備Actor得到當前溫度的協議是簡單的:ide

  • 1.等待當前溫度的請求。
  • 2.詢問時,報告最後測量的溫度(詢問時,報告最後測量的溫度或者當前溫度不可用)。

    咱們須要兩條消息,一條用於請求,另外一條用於回覆。咱們的第一次嘗試可能以下所示:性能

    這兩條消息彷佛涵蓋了所需的功能。可是,咱們選擇的方法必須考慮應用程序的分佈式特性。雖然與本地JVM上的Actor進行通訊的基本機制與遠程Actor相同,但咱們須要牢記如下幾點:

  • 本地和遠程消息之間的傳遞延遲將存在可觀察到的差別,由於網絡鏈路帶寬和消息大小等因素也會致使這個。
  • 可靠性是一個問題,由於遠程消息發送涉及更多步驟,這意味着更多可能出錯。
  • 本地發送將在同一JVM內傳遞對該消息的引用,對發送的基礎對象沒有任何限制,而遠程傳輸將對消息大小設置限制。

    此外,雖然在同一個JVM內部發送更可靠,但若是一個Actor在處理消息時因爲程序錯誤而失敗,則效果與遠程主機在處理消息時因爲遠程主機崩潰而失敗的效果相同。即便在這兩種狀況下,服務都會在一段時間後恢復(Actor由其管理者從新啓動,主機由運營商或監控系統從新啓動)在崩潰期間各個請求都會丟失。所以,Actor使得每條消息均可能丟失是悲觀的賭注。

    可是爲了進一步理解協議的靈活性需求,它將有助於考慮Akka消息排序和消息傳遞保證。Akka爲消息發送提供如下行爲。

  • 最多一次傳遞,即無保證交貨。
  • 每一個發送者,接收者對維護消息排序。

    如下部分更詳細地討論了此行爲:

消息傳遞

消息傳遞子系統提供的傳遞語義一般分爲如下幾類:

  • At-most-once delivery :每條消息傳遞零次或一次;在更多的因果關係中,這意味着消息可能會丟失,但永遠不會重複。
  • At-least-once delivery :可能會屢次嘗試傳遞每條消息,直到至少有一條消息成功;再次,在更多的因果方面,這意味着消息能夠重複,但永遠不會丟失。
  • Exactly-once delivery:每封郵件只發送一次給收件人;消息既不會丟失也不會重複。

    第一種行爲,即Akka使用的行爲,是最便宜的,而且性能最高。它具備最少的實現開銷,由於它能夠以一種即發即忘的方式完成,而不會將狀態保持在發送端或傳輸機制中。第二個,至少一次,須要重試以抵消運輸損失。這增長了將狀態保持在發送端並在接收端具備確認機制的開銷。徹底一次交付是最昂貴的,而且致使最差的性能:除了至少一次交付所增長的開銷以外,它還要求將狀態保持在接收端以便過濾掉重複的交付。

    在Actor系統中,咱們須要肯定保證的確切含義 - 系統在什麼時候將交付視爲已完成:

  1. 何時消息在網絡上發送出去?
  2. 何時目標Actor收到消息?
  3. 何時消息被放入目標Actor的郵箱時?
  4. 何時消息目標Actor開始處理消息?
  5. 目標Actor什麼時候成功處理了該消息?

    大多數聲稱保證交付的框架和協議實際上提供了相似於第4點和第5點的內容。雖然這聽起來合理,但它實際上有用嗎?要了解其含義,請考慮一個簡單實用的示例:用戶嘗試下訂單,咱們只想聲明它已經成功處理,一旦它實際上在訂單數據庫中的磁盤上。

    若是咱們依賴於成功處理消息,則只要訂單已提交給負責驗證它的內部API,處理它並將其放入數據庫,Actor就會報告成功。不幸的是,在調用API以後,可能會發生如下任何一種狀況:

  1. 主機可能崩潰。
  2. 反序列化可能會失敗。
  3. 驗證可能會失敗。
  4. 數據庫可能不可用。
  5. 可能會發生編程錯誤。

    這代表交付保證不會轉化爲域級保證。咱們只想在訂單實際徹底處理和保留後報告成功。能夠報​​告成功的惟一實體是應用程序自己,由於只有它對所需的域保證有任何瞭解。沒有通用框架能夠肯定特定域的細節以及在該域中被認爲是成功的。

    在這個特定的例子中,咱們只但願在成功的數據庫寫入以後發出成功信號,數據庫確認訂單如今已安全存儲。因爲這些緣由,Akka將保證的責任提高到應用程序自己,即您必須本身實現它們。這使您能夠徹底控制要提供的保證。如今,讓咱們考慮Akka提供的消息排序,以便於推理應用程序邏輯。

消息順序

    在Akka中,對於給定的一對Actor,從第一個發送到第二個的消息不會無序接收。

    若是:

    Actor A1將消息M1,M2,M3發送到A2。

    Actor A3將消息M4,M5,M6發送到A2。

    這意味着,對於Akka消息:

    若是M1已交付,則必須在M2和M3以前交付。

    若是M2已交付,則必須在M3以前交付。

    若是交付M4,則必須在M5和M6以前交付。

    若是M5已交付,則必須在M6以前交付。

    A2能夠看到來自A1的消息與來自A3的消息交織。

    因爲沒有保證傳送,所以能夠丟棄任何消息,即不到達A2。

    這些保證達到了很好的平衡:讓一個Actor的消息按順序到達對於構建易於推理的系統是方便的,而另外一方面容許來自不一樣Actor的消息交錯到達提供足夠的自由來有效地實現Actor系統。

    有關交付保證的完整詳細信息,請參閱參考頁面reference page.。

原文:https://doc.akka.io/docs/akka/2.5/guide/tutorial_3.html

有什麼討論的內容,能夠加我公衆號:

相關文章
相關標籤/搜索