編舞模式

Azure Event Grid
Azure 服務匯流排

分散工作流程邏輯,並將責任分散至系統內的其他元件。

內容和問題

雲端式應用程式通常會分成數個小型服務,共同處理商務交易端對端。 即使是單一作業(在交易內)也可能導致所有服務之間的多個點對點呼叫。 在理想情況下,這些服務應該鬆散結合。 設計分散式、有效率且可調整的工作流程是一項挑戰,因為它通常牽涉到複雜的服務間通訊。

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

使用中央協調器處理要求的工作流程圖表。

協調器模式通常會實作為自定義軟體,並具備這些服務責任的網域知識。 優點是協調器可以根據下游服務所執行之個別作業的結果來合併交易的狀態。

不過,有一些缺點。 新增或移除服務可能會中斷現有的邏輯,因為您需要重新連接通訊路徑的部分。 此相依性可讓協調器實作變得複雜且難以維護。 協調器可能會對工作負載的可靠性產生負面影響。 在負載下,它可能會造成效能瓶頸,並成為單一失敗點。 它也可能會導致下游服務中的串聯失敗。

解決方案

委派服務之間的事務處理邏輯。 讓每個服務決定並參與商務作業的通訊工作流程。

此模式是將集中通訊工作流程的自定義軟體相依性降到最低的方式。 元件會實作一般邏輯,因為它們會自行編排工作流程,而不會彼此直接通訊。

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

顯示使用訊息代理程序處理要求的圖表。

  1. 用戶端要求會排入佇列作為訊息代理程式中的訊息。

  2. 服務或訂閱者會輪詢訊息代理程式,以判斷它們是否可以根據其實作的商業規則來處理該訊息。 訊息代理程式也可以將訊息推送至對該訊息感興趣的訂閱者。

  3. 每個訂閱的服務都會執行其作業,如訊息所指示,並回應作業成功或失敗的訊息代理程式。

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

問題和考量

分散協調器可能會導致管理工作流程時發生問題。

  • 交接失敗可能具有挑戰性。 應用程式中的元件可能會執行不可部分完成的工作,但它們可能仍有相依性層級。 某個元件中的失敗可能會影響其他元件,這可能會造成完成整體要求的延遲。

    若要正常處理失敗,實 作補償交易 可能會帶來複雜性。

    流程圖,顯示編舞模式中的錯誤處理。

  • 此模式適用於平行處理獨立商務作業的工作流程。 當編舞需要以序列進行時,工作流程可能會變得複雜。 例如,服務 D 只能在服務 B 和服務 C 順利完成其作業之後,才能啟動其作業。

    傳訊系統中工作流程的圖表,其會平行且後續實作編舞模式。

  • 如果服務數量迅速成長,模式就會成為挑戰。 假設有大量的獨立行動元件,服務之間的工作流程通常會變得複雜。 此外,分散式追蹤變得困難。

  • 在協調器導向的設計中,中央元件可以部分參與並將復原邏輯委派給另一個元件,以一致的方式重試暫時性、非轉移和逾時失敗。 在編舞模式中解體協調器時,下游元件不應該挑選那些復原工作。 這些仍必須由復原處理程序處理。 但現在,下游元件必須與復原處理程式直接通訊,以增加點對點通訊。

使用此模式的時機

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

  • 下游元件會獨立處理不可部分完成的作業。 把它想像成一種“火和忘記”機制。 元件負責不需要主動管理的工作。 工作完成時,它會將通知傳送給其他元件。

  • 元件預期會經常更新和取代。 此模式可讓應用程式以較少的工作量和最少的中斷來修改現有服務。

  • 此模式很適合適用於簡單工作流程的無伺服器架構。 元件可以是短期和事件驅動。 事件發生時,元件會啟動、執行其工作,並在工作完成後移除。

  • 中央協調器引進效能瓶頸。

當下列情況時,此模式可能不實用:

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

  • 在某些情況下,元件之間的點對點通訊是不可避免的。

  • 您必須使用商業規則來合併下游元件處理的所有作業。

工作負載設計

架構設計人員應該評估在工作負載的設計中如何使用編舞模式,以解決 Azure 架構架構支柱涵蓋的目標和原則。 例如:

要素 此模式如何支援支柱目標
營運卓越可透過標準化的流程和小組凝聚力,協助提供工作負載品質 由於此模式中的分散式元件是自發的,且設計為可取代,因此您可以修改工作負載,整體變更較少的系統。

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

- PE:02 容量規劃
- PE:05 調整和分割

如同任何設計決策,請考慮對其他可能以此模式導入之目標的任何取捨。

範例

此範例會藉由建立事件驅動、雲端原生工作負載以及微服務來執行函式,來示範編舞模式。 當用戶端要求寄送套件時,工作負載會指派無人機。 一旦包裹準備好由排程的無人機進行挑選,就會開始傳遞程式。 在傳輸中時,工作負載會處理傳遞,直到它取得出貨狀態為止。

此範例是無人機傳遞實作的重構,以編舞模式取代 Orchestrator 模式。

實作編舞模式的事件驅動雲端原生範例工作負載圖表

擷取服務會處理用戶端要求,並將其轉換成訊息,包括傳遞詳細數據。 取用這些新訊息之後,就會起始商務交易。

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

  1. 建立或更新套件
  2. 指派無人機以傳遞包裹
  3. 處理由檢查和最終在出貨時提高認知的傳遞。

三個微服務會執行商務處理:套件、無人機排程器和傳遞服務。 服務會使用訊息彼此通訊,而不是中央協調器。 每項服務都會負責事先實作通訊協定,以分散的方式協調商務工作流程。

設計

商務交易會透過多個躍點以序列處理。 每個躍點都會在所有商務服務之間共用單一訊息總線。

當用戶端透過 HTTP 端點傳送傳遞要求時,擷取服務會收到它、將這類要求轉換成訊息,然後將訊息發佈至共用訊息總線。 已訂閱的商務服務將會取用新增至總線的新訊息。 在收到訊息時,商務服務可以完成作業並成功、失敗或要求可能會逾時。如果成功,服務會以 [確定] 狀態代碼回應總線、引發新的作業訊息,並將它傳送至訊息總線。 如果發生失敗或逾時,服務會藉由將原因碼傳送至訊息總線來報告失敗。 此外,訊息會新增至寄不出的信件佇列。 在合理且適當的時間內無法接收或處理的訊息也會移動 DLQ。

設計會使用多個訊息總線來處理整個商務交易。 Microsoft Azure 服務匯流排 和 Microsoft Azure 事件方格 是由提供此設計之傳訊服務平臺所組成。 工作負載會部署在裝載 Azure Functions 以進行擷取的 Azure Container Apps 上,以及處理執行商業規則的事件驅動處理的應用程式。

設計可確保以序列進行編排。 單一 Azure 服務匯流排 命名空間包含具有兩個訂用帳戶和會話感知佇列的主題。 擷取服務會將訊息發佈至主題。 套件服務和無人機排程器服務會訂閱主題,併發佈訊息,以將成功傳達給佇列。 包含與傳遞標識符相關聯之 GUID 的通用會話識別碼,可讓您排序處理未繫結的相關訊息序列。 傳遞服務會等候每個交易的兩個相關訊息。 第一則訊息表示包裹已準備好出貨,而第二則表示無人機已排程。

此設計會使用 Azure 服務匯流排 來處理在整個傳遞過程中無法遺失或重複的高價值訊息。 套件出貨時,也會將狀態變更發佈為 Azure 事件方格。 在此設計中,事件傳送者對處理狀態變更沒有任何期望。 不屬於此設計一部分的下游組織服務可以接聽此事件類型,並回應執行特定商業目的邏輯(也就是將出貨訂單狀態傳送給使用者)。

如果您打算將此部署至另一個計算服務,例如AKS pub-sub 模式應用程式沸騰板,可以在相同的Pod中實作兩個容器。 一個容器會 執行與喜好設定訊息總線互動的大使 ,而另一個容器則執行商業規則。 在相同 Pod 中使用兩個容器的方法可改善效能和延展性。 大使和商務服務會共用相同的網路,以允許低延遲和高輸送量。

為了避免可能導致多項工作的串聯重試作業,商務服務應立即標幟無法接受的訊息。 您可以使用已知的原因代碼或定義的應用程式程式代碼來擴充這類訊息,以便將其移至寄不出的信件佇列 (DLQ)。 請考慮管理從下游服務實作 Saga 的一致性問題。 例如,另一個服務只能藉由執行補償、重新傳送或樞紐交易來處理無效的信件訊息,以便補救。

商務服務具有等冪性,以確保重試作業不會產生重複的資源。 例如,封裝服務會使用 upsert 作業將數據新增至數據存放區。

請在設計中考慮這些模式以進行編舞。