異步傳訊選項

Azure 事件中樞
Azure Event Grid
Azure 服務匯流排
Azure 串流分析

本文說明不同類型的訊息和參與傳訊基礎結構的實體。 根據每個訊息類型的需求,本文會建議 Azure 傳訊服務。 選項包括 Azure 服務匯流排 傳訊、Azure 事件方格 和 Azure 事件中樞。 如需產品比較,請參閱 比較傳訊服務

在架構層級,訊息是由實體(產生者)所建立的數據報,用來散發資訊,讓其他實體(取用者)可以感知並據以採取行動。 產生者和取用者可以直接或選擇性地透過中繼實體(訊息代理程式)進行通訊。 本文著重於使用訊息代理程序進行異步傳訊。

Diagram demonstrating entities that take part in asynchronous messaging.

我們可以將訊息分類為兩個主要類別。 如果產生者需要取用者的動作,該訊息就是 命令。 如果訊息通知取用者已採取動作,則訊息為 事件

命令

產生者會傳送命令,其意圖是取用者會在商務交易範圍內執行作業。

命令是高價值訊息,必須至少傳遞一次。 如果命令遺失,整個商務交易可能會失敗。 此外,不應該多次處理命令。 這樣做可能會導致錯誤的交易。 客戶可能會收到重複的訂單或兩次計費。

命令通常用來管理多步驟商務交易的工作流程。 根據商業規則,產生者可能會預期取用者會認可訊息並報告作業的結果。 根據該結果,產生者可能會選擇適當的行動路線。

事件

事件是產生者為了宣佈事實而引發的訊息類型。

產生者(在此內容中稱為 發行者 )沒有任何預期事件會導致任何動作。

感興趣的取用者可以訂閱、接聽事件,並根據取用案例採取動作。 事件可以有多個訂閱者,或完全沒有訂閱者。 兩個不同的訂閱者可以回應具有不同動作的事件,而不知道彼此。

生產者和取用者會獨立結合和管理。 生產者不會預期取用者會向生產者認可事件。 不再對事件感興趣的取用者可以取消訂閱,這會從管線中移除取用者,而不會影響產生者或系統的整體功能。

事件有兩種類別:

  • 製作人提出事件,以宣佈離散事實。 常見的使用案例是事件通知。 例如,Azure Resource Manager 會在建立、修改或刪除資源時引發事件。 這些事件的訂閱者可能是傳送警示電子郵件的邏輯應用程式。

  • 產生者會在一段時間內以序列或事件串流引發相關事件。 一般而言,會取用數據流進行統計評估。 評估可以在時態時間範圍內發生,或事件到達時發生。 遙測是常見的使用案例(例如,系統的健康情況和負載監視)。 另一個案例是來自IoT裝置的事件串流。

實作事件傳訊的常見模式是 「發行者-訂閱者 」模式。

Diagram of Publisher-Subscriber pattern for event messaging.

訊息代理程式的角色和優點

中繼訊息代理程式提供將訊息從產生者移至取用者的功能,並提供更多優點。

縮減

訊息代理程式會將產生者與邏輯中的取用者分離,而該邏輯會分別產生和使用訊息。 在複雜的工作流程中,訊息代理程式可以鼓勵業務作業分離,並協助協調工作流程。

例如,單一商務交易需要以商業規則順序執行的不同作業。 產生者發出命令,向取用者發出啟動作業的訊號。 取用者會在保留給產生者回應的個別佇列中認可訊息。 只有在收到回應之後,產生者才會傳送新訊息,以在序列中啟動下一個作業。 不同的取用者會處理該訊息,並將完成訊息傳送至回應佇列。 藉由使用傳訊,服務會協調彼此之間交易的工作流程。

Diagram of producer-consumer communication.

訊息代理程式提供時態分離。 生產者和取用者不需要同時執行。 不論取用者的可用性為何,產生者都可以將訊息傳送給訊息代理程式。 相反地,取用者不會受限於生產者的可用性。

例如,Web 應用程式的使用者介面會產生訊息,並使用佇列作為訊息代理程式。 當取用者就緒時,它可以從佇列擷取訊息並執行工作。 時態分離可協助使用者介面保持回應。 當訊息以異步方式處理時,不會封鎖它。

某些作業可能需要很長的時間才能完成。 發出命令之後,產生者不應該等到取用者完成它。 訊息代理程式可協助異步處理訊息。

負載平衡

產生者可以張貼大量由許多取用者提供服務的訊息。 使用訊息代理程式將處理分散到伺服器並改善輸送量。 取用者可以在不同的伺服器上執行,以分散負載。 您可以視需要或移除,動態新增取用者以相應放大系統。

Diagram of Competing Consumers pattern.

競爭取用者模式說明如何同時處理多個訊息,以優化輸送量、改善延展性和可用性,以及平衡工作負載。

負載調節

產生者或產生者群組所產生的訊息量可以是可變的。 有時可能會有大量的磁碟區造成訊息尖峰。 訊息代理程式不需新增取用者來處理這項工作,而是可以做為緩衝區,取用者會以自己的步調逐步清空訊息,而不會對系統產生壓力。

Diagram of Queue-based Load Leveling pattern.

佇列 型負載撫平模式 提供詳細資訊。

可靠的傳訊

訊息代理程式可協助確保即使產生者和取用者之間的通訊失敗,訊息也不會遺失。 產生者可以將訊息張貼至訊息代理程式,而取用者可以在重新建立通訊時擷取訊息。 除非產生者與訊息代理程式失去連線,否則不會遭到封鎖。

復原傳訊

訊息代理程式可以將復原功能新增至您系統中的取用者。 如果取用者在處理訊息時失敗,則取用者的另一個實例可以處理該訊息。 因為訊息會保存在訊息代理程式中,因此可能會進行重新處理。

訊息代理程序的技術選擇

Azure 提供數個訊息代理程式服務,每個服務都有一系列功能。 選擇服務之前,請先判斷訊息的意圖和需求。

Azure 服務匯流排 傳訊

Azure 服務匯流排 傳訊佇列非常適合將命令從產生者傳輸到取用者。 以下是一些考慮。

提取模型

服務匯流排 佇列的取用者會持續輪詢 服務匯流排,以檢查是否有新訊息可用。 用戶端 SDK 和 Azure Functions 觸發程式,用於 服務匯流排 該模型抽象化。 當有新的訊息可用時,會叫用取用者的回呼,並將訊息傳送給取用者。

保證傳遞

服務匯流排 可讓取用者查看佇列,並鎖定來自其他取用者的訊息。

消費者有責任報告訊息的處理狀態。 只有當取用者將訊息標示為已取用時,才會 服務匯流排 從佇列中移除訊息。 如果發生失敗、逾時或當機,服務匯流排 解除鎖定訊息,讓其他取用者可以擷取訊息。 如此一來,傳輸中就不會遺失訊息。

產生者可能會不小心傳送相同的訊息兩次。 例如,傳送訊息之後,產生者實例會失敗。 另一個產生者會取代原始實例,並再次傳送訊息。 Azure 服務匯流排 佇列提供內建的清除功能,可偵測並移除重複的訊息。 仍有機會傳遞訊息兩次。 例如,如果取用者在處理時失敗,訊息會傳回至佇列,並由相同或另一個取用者擷取。 取用者中的訊息處理邏輯應該具有等冪性,如此一來,即使重複工作,系統的狀態也不會變更。

訊息順序

如果您想要取用者依照訊息傳送的順序取得訊息,服務匯流排 佇列會使用會話來保證先出 (FIFO) 已排序傳遞。 會話可以有一或多個訊息。 訊息會與 SessionId 屬性相互關聯。 屬於會話一部分的訊息,永遠不會過期。 會話可以鎖定給取用者,以防止其訊息由不同的取用者處理。

如需詳細資訊,請參閱 訊息會話

訊息持續性

服務總線佇列支持時態分離。 即使取用者無法使用或無法處理訊息,它仍會保留在佇列中。

檢查點長時間執行的交易

商務交易可以長時間執行。 交易中的每個作業都可以有多個訊息。 使用檢查點協調工作流程,並在交易失敗時提供復原能力。

服務匯流排 佇列允許透過工作階段狀態功能進行檢查點。 狀態資訊會以累加方式記錄在佇列 (SetState) 中屬於會話的訊息。 例如,取用者可以立即檢查狀態 (GetState) 來追蹤進度。 如果取用者失敗,另一個取用者可以使用狀態信息來判斷最後一個已知檢查點以繼續會話。

寄不出的信件佇列 (DLQ)

服務匯流排 佇列有預設子佇列,稱為寄不出的信件佇列 (DLQ),以保存無法傳遞或處理的訊息。 服務匯流排 或取用者中的訊息處理邏輯可以將訊息新增至 DLQ。 DLQ 會保留訊息,直到從佇列擷取訊息為止。

以下是訊息最終可能出現在 DLQ 中的範例:

  • 有害訊息是無法處理的訊息,因為它的格式不正確或包含非預期的資訊。 在 服務匯流排 佇列中,您可以設定佇列的 MaxDeliveryCount 屬性來偵測有害訊息。 如果收到相同訊息的次數超過該屬性值,服務匯流排 會將訊息移至 DLQ。

  • 如果訊息在一段時間內未處理,可能不再相關。 服務匯流排 佇列可讓產生者張貼具有生存時間屬性的訊息。 如果此期間在收到訊息之前到期,訊息會放在 DLQ 中。

檢查 DLQ 中的訊息,以判斷失敗原因。

混合式解決方案

服務匯流排橋接內部部署系統和雲端解決方案。 由於防火牆限制,內部部署系統通常難以觸達。 生產者和取用者(可以是內部部署或雲端)都可以使用 服務匯流排 佇列端點作為訊息的取貨和下車位置。

訊網橋模式 是處理這些案例的另一種方式。

主題和訂閱

服務匯流排 透過 服務匯流排 主題和訂用帳戶支援 Publisher-Subscriber 模式。

此功能提供一種方式,讓產生者向多個取用者廣播訊息。 當主題收到訊息時,會轉送給所有已訂閱的取用者。 或者,訂用帳戶可以有篩選準則,可讓取用者取得訊息的子集。 每個取用者會以類似佇列的方式,從訂用帳戶擷取訊息。

如需詳細資訊,請參閱 Azure 服務匯流排 主題

事件格線

我們建議針對離散事件 Azure 事件方格。 事件方格遵循 Publisher-Subscriber 模式。 當事件來源觸發事件時,它們會發佈至 事件方格主題。 這些事件的取用者會藉由指定將處理事件的事件類型和事件處理程式,來建立 Event Grid 訂用帳戶。 如果沒有訂閱者,則會捨棄事件。 每個事件可以有多個訂用帳戶。

推送模型

事件方格會將訊息傳播至推送模型中的訂閱者。 假設您有具有 Webhook 的事件方格訂用帳戶。 當新的事件送達時,Event Grid 會將事件張貼至 Webhook 端點。

與 Azure 整合

如果您想要取得 Azure 資源的通知,請選擇 [事件方格]。 許多 Azure 服務會作為 具有內建事件方格主題的事件來源 。 Event Grid 也支援各種可設定為 事件處理程式的 Azure 服務。 您可以輕易訂閱這些主題,將事件路由至您選擇的事件處理程式。 例如,您可以在建立或刪除 Blob 記憶體時,使用事件方格來叫用 Azure 函式。

自訂主題

如果您想要從應用程式或未與事件方格整合的 Azure 服務傳送事件,請建立自定義事件方格主題。

例如,若要查看整個商務交易的進度,您希望參與的服務在處理個別商務作業時引發事件。 Web 應用程式會顯示這些事件。 完成這項工作的其中一種方式是建立自定義主題,並使用透過 HTTP WebHook 註冊的 Web 應用程式新增訂用帳戶。 當商務服務將事件傳送至自定義主題時,事件方格會將事件推送至您的 Web 應用程式。

篩選的事件

您可以在訂用帳戶中指定篩選,以指示事件方格只將事件子集路由傳送至特定事件處理程式。 您可以在訂用帳戶架構指定篩選。 傳送至主題且值符合篩選的任何事件,都會自動轉送至該訂用帳戶。

例如,各種格式的內容會上傳至 Blob 儲存體。 每次新增檔案時,都會引發事件併發佈至事件方格。 事件訂閱可能會有篩選條件,只傳送影像的事件,讓事件處理程式可以產生縮圖。

如需篩選的詳細資訊,請參閱 篩選事件方格的事件。

高輸送量

事件方格可以路由傳送每個區域每秒 10,000,000 個事件。 每月的前 100,000 個作業免費。 如需成本考慮,請參閱 事件方格的成本是多少?

復原傳遞

即使成功的事件傳遞不如命令那麼重要,您仍可能仍需要一些保證,視事件類型而定。 事件方格提供您可以啟用和自定義的功能,例如重試原則、到期時間和寄不出的信件。 如需詳細資訊,請參閱 事件方格訊息傳遞和重試

事件方格的重試程式可協助復原,但無法安全。 在重試程式中,如果端點長時間沒有回應,事件方格可能會傳遞訊息一次以上、略過或延遲某些重試。 如需詳細資訊,請參閱 重試排程

您可以啟用寄不出的信件,將未傳遞的事件保存到 Blob 記憶體帳戶。 將訊息傳遞至 Blob 記憶體端點的延遲,如果該端點沒有回應,則事件方格會捨棄事件。 如需詳細資訊,請參閱 設定寄不出的信件位置和重試原則

Azure 事件中樞

當您使用事件數據流時,Azure 事件中樞 是建議的訊息代理程式。 基本上,它是一個大型緩衝區,能夠接收低延遲的大量數據。 接收的數據可以透過並行作業快速讀取。 您可以使用任何即時分析提供者來轉換已接收的數據。 事件中樞也提供將事件儲存在記憶體帳戶的功能。

快速擷取

事件中樞每秒可以擷取數百萬個事件。 事件只會附加至數據流,並依時間排序。

提取模型

與事件方格一樣,事件中樞也提供「發行者-訂閱者」功能。 事件方格與事件中樞之間的主要差異在於事件數據可供訂閱者使用的方式。 事件方格會將擷取的數據推送至訂閱者,而事件中樞則會在提取模型中提供數據。 收到事件時,事件中樞會將事件中樞附加至數據流。 訂閱者會管理其數據指標,而且可以在數據流中向前和往回移動、選取時間位移,以及依其步調重新執行序列。

數據流處理器是針對轉換和統計分析的目的,從事件中樞提取數據的訂閱者。 使用 Azure 串流分析和Apache Spark 進行複雜的處理,例如一段時間的匯總或異常偵測。

如果您想要針對每個分割區的每個事件採取行動,您可以使用事件處理器主機,或使用 Azure Logic Apps內建連接器來提取數據,以提供轉換邏輯。 另一個選項是使用 Azure Functions

資料分割

分割區是事件數據流的一部分。 事件會使用分割區索引鍵來分割。 例如,數個IoT裝置會將裝置資料傳送至事件中樞。 分割區索引鍵是裝置標識碼。 當事件內嵌時,事件中樞會將事件中樞移至不同的分割區。 在每個分割區內,所有事件都會依時間排序。

取用者是處理事件數據的程式代碼實例。 事件中樞遵循分割取用者模式。 每個取用者只會讀取特定的分割區。 有多個分割區會導致處理速度較快,因為多個取用者可以同時讀取數據流。

相同取用者的實例組成單一取用者群組。 多個取用者群組可以讀取具有不同意圖的相同數據流。 假設事件數據流具有來自溫度感測器的數據。 一個取用者群組可以讀取數據流,以偵測異常狀況,例如溫度的尖峰。 另一個可以讀取相同的數據流,以計算時態視窗中的滾動平均溫度。

事件中樞支持發行者-訂閱者模式,方法是允許多個取用者群組。 每個取用者群組都是訂閱者。

如需事件中樞數據分割的詳細資訊,請參閱 數據分割

事件中樞擷取

擷取功能可讓您將事件串流儲存至 Azure Blob 記憶體Data Lake 儲存體。 這種儲存事件的方式是可靠的,因為即使記憶體帳戶無法使用,擷取會保留您的數據一段時間,然後在記憶體可用之後寫入記憶體。

儲存體 服務也可以提供其他功能來分析事件。 例如,藉由利用 Blob 記憶體帳戶的存取層,您可以針對需要經常存取的數據,將事件儲存在經常性存取層中。 您可以使用該資料進行視覺效果。 或者,您可以將數據儲存在封存層中,並偶爾擷取數據以供稽核之用。

擷取會 儲存事件中樞所擷取的所有 事件,而且適用於批處理。 您可以使用 MapReduce 函式來產生資料報告。 擷取的數據也可以做為事實來源。 如果匯總數據時遺漏某些事實,您可以參考擷取的數據。

如需這項功能的詳細資訊,請參閱在 Azure Blob 儲存體 或 Azure Data Lake 儲存體 中透過 Azure 事件中樞 擷取事件。

支援 Apache Kafka 用戶端

事件中樞提供 Apache Kafka 用戶端的端點。 現有的用戶端可以更新其設定以指向端點,並開始將事件傳送至事件中樞。 您不需要進行任何程式代碼變更。

如需詳細資訊,請參閱 適用於 Apache Kafka 的事件中樞

交叉案例

在某些情況下,結合兩個傳訊服務是有好處的。

結合服務可以提升訊息系統的效率。 例如,在您的商務交易中,您會使用 Azure 服務匯流排 佇列來處理訊息。 大部分閑置且偶爾接收訊息的佇列效率不佳,因為取用者會持續輪詢佇列中是否有新訊息。 您可以使用 Azure 函式作為事件處理程式來設定 Event Grid 訂用帳戶。 每次佇列收到訊息且沒有取用者接聽時,Event Grid 都會傳送通知,以叫用清空佇列的 Azure 函式。

Diagram of Azure Service Bus to Event Grid integration.

如需將 服務匯流排 連線至事件方格的詳細資訊,請參閱 Azure 服務匯流排 事件方格整合概觀

使用消息佇列和事件參考架構的企業整合會顯示事件方格整合 服務匯流排 實作。

以下是另一個範例:事件方格會收到一組事件,其中某些事件需要工作流程,而其他事件則用於通知。 訊息元數據會指出事件的類型。 區別的其中一種方式是使用事件訂用帳戶中的篩選功能來檢查元數據。 如果它需要工作流程,事件方格會將它傳送至 Azure 服務匯流排 佇列。 該佇列的接收者可以採取必要的動作。 通知事件會傳送至 Logic Apps 以傳送警示電子郵件。

Diagram of Azure Event Grid to Service Bus integration.

實作異步傳訊時,請考慮這些模式:

  • 競爭取用者模式。 多個取用者可能需要競爭才能從佇列讀取訊息。 此模式說明如何同時處理多個訊息,以優化輸送量、改善延展性和可用性,以及平衡工作負載。
  • 優先順序佇列模式。 對於商業規則要求某些訊息在其他訊息之前處理的情況,此模式描述產生者所張貼的訊息優先順序較高,且取用者比優先順序較低的訊息更快處理。
  • 佇列型負載撫平模式。 此模式會使用訊息代理程式作為產生者和取用者之間的緩衝區,以協助將這兩個實體間歇性繁重負載的可用性和回應性的影響降到最低。
  • 重試模式。 產生者或取用者可能無法連線到佇列,但此失敗的原因可能是暫時性且快速傳遞。 此模式描述如何處理這種情況,以將復原功能新增至應用程式。
  • 排程器代理程式監督員模式。 傳訊通常用於工作流程實作的一部分。 此模式示範傳訊如何協調一組分散式服務和其他遠端資源的動作,以及讓系統復原和重試失敗的動作。
  • 編舞模式。 此模式顯示服務如何使用傳訊來控制商務交易的工作流程。
  • 宣告檢查模式。 此模式示範如何將大型訊息分割成宣告檢查和承載。

社群資源

喬納森·奧利弗的部落格文章:等冪性

馬丁·福勒的部落格文章:你的意思是「事件驅動」是什麼意思?