共用方式為


編舞模式

編舞模式將工作流程邏輯去中心化,並將責任分配給系統內的其他元件。 服務部門不再依賴中央協調者,而是決定何時以及如何處理業務運作。

內容和問題

通常你會將雲端應用程式拆分成幾個小型服務,這些服務協同運作以處理端到端的商業交易。 交易中的單一操作可能導致所有服務間多次點對點通話。 理想狀況下,這些服務是鬆散耦合的。 設計分散式、高效且可擴展的工作流程具有挑戰性,因為它涉及複雜的服務間溝通。

通訊的常見模式是使用集中式服務或 協調器。 傳入要求會流經協調器,因為它會將作業委派給個別的服務。 每個服務都完成了自己的責任,卻不了解整體工作流程。

一個使用中央協調器處理請求的工作流程圖示。

你通常會以自訂軟體實作編排器模式,具備系統內服務職責的領域知識。 此方法的一個好處是,協調器能根據下游服務執行的個別操作結果整合交易狀態。

這種做法也帶來一些障礙。 新增或移除服務可能會中斷現有的邏輯,因為您需要重新連接通訊路徑的部分。 此相依性可讓協調器實作變得複雜且難以維護。 編排器可能會對工作負載的可靠性產生負面影響。 在負載情況下,它可能會導致效能瓶頸,並成為單一故障點(SPoF)。 它也可能會導致下游服務中的連鎖故障。

解決方案

將交易處理邏輯委派給各服務。 讓每個服務參與企業營運的通訊工作流程,並決定何時以及如何處理。

編舞模式減少了對集中化溝通流程的客製化軟體的依賴。 這些元件在彼此間編排工作流程時,實作共同邏輯,且彼此之間不直接溝通。

實作編舞的常見方式是使用訊息代理程式來緩衝要求,直到下游元件宣告並處理這些要求為止。 下圖顯示透過 發布者-訂閱者模式處理請求。

一個顯示訊息中介如何處理請求的圖表。

  1. 客戶端請求會在訊息代理中作為訊息佇列。

  2. 服務或用戶會輪詢經紀人,以判斷其是否能根據實作的業務邏輯處理該訊息。 經紀商也能向有興趣的訂閱者推送訊息。

  3. 每個訂閱服務依訊息指示執行其操作,並以操作成功或失敗訊息回應經紀人。

  4. 若操作成功,服務可將訊息推回同一佇列或不同佇列,讓其他服務在需要時繼續該工作流程。 如果作業失敗,訊息代理程式會與其他服務搭配運作,以補償該作業或整個交易。

問題和考慮

在決定如何實施此模式時,請考慮以下幾點:

使用此模式的時機

當下列情況時,請使用此模式:

  • 下游元件會獨立地處理原子操作。 可以把這種模式想像成一種 「開火後忘記 」機制,元件執行不需要主動管理的任務。 當任務完成後,元件會向其他元件發送通知。

  • 你預期會經常更新和更換這些元件。 這種模式讓你能以較少的努力修改應用程式,且對現有服務的干擾最小。

  • 你使用無伺服器架構來進行簡單的工作流程。 元件可以是短暫的和事件驅動的。 當事件發生時,服務會建立執行任務的元件,完成該任務後則移除元件。

  • 有界上下文之間的通訊需要跨領域邊界的鬆散耦合。 若在單一有界上下文內進行通訊,則應應用編排器模式。

  • 中央調度器引入了性能瓶頸。

在下列情況下,此模式可能不適用:

  • 應用程式很複雜,需要中央元件來處理共享邏輯,讓下游元件保持輕量。

  • 元件間的點對點通訊是不可避免的。

  • 你需要使用商業邏輯來整合所有下游元件處理的操作。

工作負載設計

評估如何在工作負載設計中使用編舞模式,以達成 Azure Well-Architected Framework 支柱所涵蓋的目標與原則。 下表提供此模式如何支援每個要素目標的指引。

支柱 此模式如何支援支柱目標
卓越營運有助於透過標準化流程和團隊凝聚力來提供工作負載品質 這種模式中的分散式元件是自主的,設計上可替換,因此你可以調整工作負載,且對系統整體的改變較少。

- OE:04 工具和程式
效能效率 可透過調整、數據和程式碼的優化, 有效率地協助您的工作負載符合需求 當集中式協調流程拓撲發生效能瓶頸時,此模式提供替代方式。

- PE:02 容量規劃
- PE:05 縮放和分區

如果此模式在一個支柱內部引入取捨,請將它們與其他支柱的目標進行考量。

範例

此範例展示了編舞模式,透過建立事件驅動的雲端原生工作負載,將函式與微服務並行運行。 當客戶端要求寄送包裹時,工作負載會指派一台無人機。 包裹準備好由預定的無人機取走後,投遞程序便開始。 包裹在運送途中,工作負載會負責處理運送過程,直到收到已出貨的狀態。

一個事件驅動、雲端原生範例工作負載的示意圖,實作了編舞模式。

資料擷取服務會接收客戶端請求並將其轉換為包含傳遞細節的訊息。 商務交易會在服務接收這些新訊息後開始。

單一用戶端商務交易需要三個不同的商務作業:

  • 建立或更新套件。

  • 指派無人機送包裹。

  • 負責配送,包括檢查並在包裹出貨時發送通知。

包裹、無人機排程器及配送微服務負責業務處理。 這些服務之間使用訊息傳遞,而非中央協調器來彼此溝通。 每個服務都必須事先實作一套協議,以去中心化的方式協調業務工作流程。

Design

服務會依序透過多跳處理業務交易。 每個跳點在所有商業服務間共用一條訊息匯流排。

當用戶端透過 HTTP 端點發送傳送請求時,擷取服務會接收該請求,將其轉換成訊息,然後將訊息發佈到共享訊息匯流排。 訂閱的商業服務會讀取新增到匯流排上的訊息。 當商業服務收到訊息時,這表示操作已成功完成、請求失敗或逾時。若請求成功,服務會以狀態碼Ok 回應訊息匯流排,產生新的操作訊息並將其送到訊息匯流排。 若請求失敗或逾時,服務會將原因碼傳送至訊息匯流排,然後將訊息加入死信佇列(DLQ)以回報失敗。 服務也會將無法在特定時間內接收或處理的訊息移至 DLQ。

此設計利用多重訊息匯流排來處理整個商業交易。 Azure Service BusAzure Event Grid 提供此設計的訊息服務平台。 該工作負載運行於 Azure Container Apps,該容器會承載 Azure Functions 供擷取。 容器應用程式處理執行業務邏輯的 事件驅動處理

這種設計也確保編舞是有順序的。 單一服務匯流排命名空間包含一個主題,該主題包含兩個訂閱及一個會話感知佇列。 資料引入服務會向主題名稱發布訊息。 套件服務與無人機排程服務會訂閱主題並發布訊息,通知隊列成功請求。 加入一個共用的會話識別碼,將 GUID 與傳遞識別碼關聯起來,讓服務能依序處理無界的相關訊息序列。 配送服務會等待每筆交易的兩則相關訊息。 第一個訊息表示包裹已準備好出貨,第二個則表示無人機已排程。

在此設計中,服務匯流排處理高價值訊息,且在整個傳遞過程中不得遺失或重複。 當套件出貨時,狀態變更會發布到 Event Grid。 事件發送者對狀態變更的處理方式沒有預期。 此設計未包含的下游組織服務可監聽此事件類型並執行特定商業邏輯,例如向使用者發送訂單狀態電子郵件。

如果你將此模式部署於其他運算服務,例如 AKS,你可以在同一個 pod 中實作 Publisher-Subscriber 模式應用樣板,並包含 兩個容器。 其中一個容器執行Ambassador,與您選擇的訊息匯流排互動,另一個容器則執行業務邏輯。 此方法提升效能與可擴展性。 大使與商業服務共用同一網路,降低延遲並提升吞吐量。

為避免連鎖重試操作導致多次嘗試,企業服務應立即標記不可接受訊息。 透過使用通用原因碼或定義的應用程式碼來豐富這些訊息,使服務能將它們移至 DLQ。 考慮實作 Saga 模式來管理下游服務的一致性問題。 例如,另一個服務僅透過執行補償、重試或樞紐交易來處理死信訊息以進行修復。

商業服務是冪等的,以確保重試操作不會產生重複資源。 例如,套件服務會使用新增或更新操作將資料加入資料存儲。

下一步

在你的編舞設計中考慮以下這些模式: