讓應用程式以異步方式向多個感興趣的取用者宣告事件,而不需要將傳送者與接收者結合。
也稱為:發佈/子訊息
內容和問題
在雲端式和分散式應用程式中,系統元件通常需要在事件發生時將資訊提供給其他元件。
異步傳訊是將發件者與取用者分離的有效方式,並避免封鎖發件者等候回應。 不過,針對每個取用者使用專用消息佇列並不會有效地調整為許多取用者。 此外,某些取用者可能只對資訊的子集感興趣。 發件者如何向所有感興趣的消費者宣佈事件,而不知道其身分識別?
解決方案
引進包含下列各項的異步傳訊子系統:
傳送者所使用的輸入傳訊通道。 傳送者會使用已知的訊息格式,將事件封裝到訊息中,並透過輸入通道傳送這些訊息。 此模式中的傳送者也稱為 發行者。
注意
訊息是數據的封包。 事件是一則訊息,會通知其他元件變更或已採取的動作。
每個取用者一個輸出傳訊通道。 取用者稱為 「訂閱者」。
針對對該訊息感興趣的所有訂閱者,將每個訊息從輸入通道複製到輸出通道的機制。 此作業通常是由訊息代理程式或事件總線等媒介處理。
下圖顯示此模式的邏輯元件:
發佈/子訊息具有下列優點:
它會分離仍然需要通訊的子系統。 子系統可以獨立管理,即使一或多個接收者脫機,也可以正確管理訊息。
它會增加延展性,並改善寄件者的回應性。 傳送者可以將單一訊息快速傳送至輸入通道,然後返回其核心處理責任。 傳訊基礎結構負責確保訊息傳遞至感興趣的訂閱者。
其可改善可靠性。 異步傳訊可協助應用程式在增加的負載下繼續順利執行,並更有效地處理間歇性失敗。
它允許延遲或排程處理。 訂閱者可以等候挑選訊息,直到離峰時間,或根據特定排程路由或處理訊息。
它可讓您在系統之間使用不同平臺、程式設計語言或通訊協定,以及內部部署系統和雲端中執行的應用程式之間,進行更簡單的整合。
它可跨企業加速異步工作流程。
它可改善可測試性。 您可以監視通道,並檢查或記錄訊息,作為整體整合測試策略的一部分。
它提供應用程式的考慮區隔。 每個應用程式都可以專注於其核心功能,而傳訊基礎結構會處理可靠地將訊息路由傳送至多個取用者所需的所有專案。
問題和考量
當您決定如何實作此模式時,請考慮下列幾點:
現有的技術。 強烈建議使用支援發佈訂閱模型的可用傳訊產品和服務,而不是自行建置。 在 Azure 中,請考慮使用 服務匯流排、事件中樞或事件方格。 可用於發佈/子訊息的其他技術包括 Redis、RabbitMQ 和 Apache Kafka。
訂閱處理。 傳訊基礎結構必須提供機制,供取用者用來訂閱或取消訂閱可用的通道。
安全性。 連線到任何訊息通道必須受到安全策略的限制,以防止未經授權的使用者或應用程式竊聽。
訊息的子集。 訂閱者通常只對發行者所散發之訊息的子集感興趣。 傳訊服務通常允許訂閱者縮小接收的訊息集:
- 主題。 每個主題都有專用的輸出通道,而且每個取用者都可以訂閱所有相關主題。
- 內容篩選。 系統會根據每個訊息的內容來檢查和散發訊息。 每個訂閱者都可以指定它感興趣的內容。
通配符訂閱者。 請考慮允許訂閱者透過通配符訂閱多個主題。
雙向通訊。 發行-訂閱系統中的通道會被視為單向。 如果特定訂閱者需要傳送通知或將狀態傳回發行者,請考慮使用 要求/回復模式。 此模式會使用一個通道將訊息傳送給訂閱者,以及個別的回復通道,以便與發行者通訊。
訊息順序。 不保證取用者實例接收訊息的順序,而且不一定反映訊息建立的順序。 設計系統以確保訊息處理具有等冪性,以協助消除訊息處理順序的任何相依性。
訊息優先順序。 某些解決方案可能需要以特定順序處理訊息。 優先順序 佇列模式 提供一種機制,可確保特定訊息在其他人之前傳遞。
有害訊息。 格式不正確的訊息,或需要存取無法使用之資源的工作,可能會導致服務實例失敗。 系統應該防止這類訊息傳回佇列。 相反地,擷取並儲存這些訊息的詳細數據,以便在必要時進行分析。 某些訊息代理程式,例如 Azure 服務匯流排,可透過寄不出的信件佇列功能來支援此訊息代理程式。
重複的訊息。 相同的訊息可能會多次傳送。 例如,傳送者在張貼郵件之後可能會失敗。 然後,寄件者的新實例可能會啟動並重複訊息。 傳訊基礎結構應該根據訊息標識碼實作重複的訊息偵測和移除(也稱為取消刪除),以提供最多一次的訊息傳遞。 或者,如果使用不會取消重複訊息的傳訊基礎結構,請確定 訊息處理邏輯具有等冪性。
訊息到期。 訊息的存留期可能有限。 如果未在此期間內處理,它可能不再相關且應該捨棄。 傳送者可以將到期時間指定為訊息中數據的一部分。 接收者可以在決定是否執行與訊息相關聯的商業規則之前,先檢查此資訊。
訊息排程。 訊息可能會暫時遭到封鎖,且不應處理到特定日期和時間為止。 在此時之前,接收者不應該使用訊息。
相應放大訂閱者。 如果指定的訂閱者無法跟上接收的訊息速率,請使用 競爭取用者模式 來相應放大。
使用此模式的時機
當下列情況時,請使用此模式:
應用程式需要向大量取用者廣播資訊。
應用程式需要與一或多個獨立開發的應用程式或服務通訊,其可能會使用不同的平臺、程式設計語言和通訊協定。
應用程式可以將資訊傳送給取用者,而不需要取用者的實時回應。
整合的系統是設計來支援其數據的最終一致性模型。
應用程式需要將資訊傳達給多個取用者,其可用性需求或運行時間排程可能與傳送者不同。
當下列情況時,此模式可能不實用:
應用程式只有少數取用者需要與產生應用程式截然不同的資訊。
應用程式需要與取用者進行近乎實時的互動。
工作負載設計
架構設計人員應該評估發行者/訂閱者模式如何用於其工作負載的設計,以解決 Azure 良好架構架構支柱中涵蓋的目標和原則。 例如:
要素 | 此模式如何支援支柱目標 |
---|---|
可靠性設計決策可協助工作負載復原到故障,並確保它會在發生失敗后復原到完全正常運作的狀態。 | 此模式中引進的分離可讓元件上的獨立可靠性目標,並移除直接相依性。 - RE:03 失敗模式分析 - RE:07 背景工作 |
安全性 設計決策有助於確保 工作負載數據和系統的機密性、 完整性和 可用性 。 | 此模式引進了重要的安全性分割界限,可讓佇列訂閱者與發行者隔離網路。 - SE:04 分割 |
成本最佳化著重於維持和改善工作負載的投資報酬率。 | 這種分離的設計可以在您的架構中啟用事件驅動方法,這與以耗用量為基礎的計費搭配良好,以避免過度布建。 - CO:05 速率優化 - CO:12 調整成本 |
營運卓越可透過標準化的流程和小組凝聚力,協助提供工作負載品質。 | 這一層間接存取可讓您安全地變更發行者端或訂閱者端的實作,而不需要協調這兩個元件的變更。 - OE:06 工作負載開發 - OE:11 安全部署做法 |
效能效率可透過調整規模、資料、程式碼達到最佳化,有效率地協助您的工作負載符合需求。 | 從取用者分離發行者可讓您針對取用者需要針對特定訊息執行的工作優化計算和程序代碼。 - PE:02 容量規劃 - PE:05 調整和分割 |
如同任何設計決策,請考慮對其他可能以此模式導入之目標的任何取捨。
範例
下圖顯示使用 服務匯流排 協調工作流程的企業整合架構,以及事件方格來通知子系統發生的事件。 如需詳細資訊,請參閱 使用消息佇列和事件在 Azure 上進行企業整合。
下一步
實作此模式時,下列指引可能相關:
選擇傳遞訊息的 Azure 服務。
異步傳訊入門。 消息佇列是異步通訊機制。 如果取用者服務需要將回復傳送至應用程式,可能需要實作某種形式的回應傳訊。 異步傳訊入門提供如何使用消息佇列實作要求/回復傳訊的資訊。
實作此模式時,下列模式可能相關:
此部落格文章 說明處理依序送達之訊息的不同方式。
相關資源
- 事件 驅動架構樣式 是使用pub/sub傳訊的架構樣式。
- 等冪訊息處理
- 使用消息佇列和事件在 Azure 上進行企業整合