共用方式為


訊息複寫和跨區域同盟

在命名空間中,Azure 服務匯流排支援使用自動轉送來建立鏈結佇列和主題訂用帳戶的拓撲,以允許實作多種不同的路由模式。 例如,您可以為合作夥伴提供他們擁有傳送或接收權限,並且可視需要暫止的私人佇列,並彈性地將其連線至應用程式專用的其他實體。 您也可以建立複雜的多階段路由拓撲,也可以建立信箱樣式的佇列,以清空類似於佇列的主題訂用帳戶,讓每個訂閱者能夠有更多儲存體容量。

許多複雜的解決方案也需要跨命名空間界限複寫訊息,才能實作這些模式和其他模式。 訊息可能必須在與多個不同的應用程式租用戶相關聯的命名空間之間,或在多個不同的 Azure 區域間流動。

您的解決方案會在不同區域中維護多個服務匯流排命名空間,並在佇列和主題之間複寫訊息,且/或您將與來源和目標 (例如 Azure 事件中樞Azure IoT 中樞Apache Kafka) 交換訊息。

這些案例是本文的重點。

同盟模式

您可能出於多種潛在的動機,而想要在佇列或主題等服務匯流排實體之間,或是服務匯流排與其他來源和目標之間移動訊息。

相較於事件中樞的類似模式集,類佇列實體的同盟更為複雜,因為訊息佇列承諾其取用者對任何單一訊息皆具有獨佔擁有權、預期會在訊息傳遞中保留抵達順序,且會讓訊息代理程式在競爭性取用者之間協調訊息的公平分配。

實際上有障礙存在 (包括 CAP 定理的條件約束),因而難以提供在多個區域中同時呈現的統一佇列檢視,並允許分散於不同區域的競爭性取用者獲得訊息的獨佔擁有權。 這類異地分散式佇列不僅需要完全一致地複寫訊息,也需要這樣複寫每個訊息的傳遞狀態,訊息才可供取用者使用。 假設的區域分散式佇列達到完整一致性的目標,與所有 Azure 服務匯流排客戶在考量同盟案例時實際的主要目標直接衝突:解決方案要達到最大的可用性和可靠性。

因此,此處呈現的模式著重於可用性和可靠性,同時要設法避免資訊遺失和重複處理訊息。

針對區域可用性事件的復原能力

儘管最高可用性和可靠性是服務匯流排的首要操作優先順序,但仍有許多方式可能會使生產者或取用者因網路或名稱解析問題而無法與指派的「主要」服務匯流排交談,或服務匯流排實體可能真的暫時沒有回應,或傳回錯誤。 指定的訊息處理器也可能變得無法使用。

這類情況並不是「災難」,以致您會想要完全放棄區域部署,就像您可能在災害復原情況下所做的一樣,但是某些應用程式的商務案例可能已受到持續不超過幾分鐘或甚至幾秒鐘的可用性事件所影響。 Azure 服務匯流排常用於混合式雲端環境,以及位於網路邊緣的用戶端,例如零售商店、餐廳、銀行支點、製造廠、物流設施及機場。 由於網路路由或壅塞問題的影響,一個站台可能會無法連線到其指派的服務匯流排端點,但可連線到不同區域中的次要端點。 同時,處理來自這些站台之訊息的系統或許仍可無礙地存取主要和次要服務匯流排端點。

這類混合式雲端和邊緣應用程式的實際範例有很多,它們對於網路路由問題或服務匯流排實體的暫時可用性問題所產生的影響,在業務上的容忍度較低。 這些範例包括在零售據點處理付款、在機場門進行登機,以及在餐廳使用行動電話點餐等,一旦沒有可靠的通訊路徑可供使用,這一切都會動彈不得。

在此類別中,我們會討論三個不同的分散式模式:「全主動」複寫、「主動-被動」複寫,和「溢出」複寫。

全主動複寫

「全主動」複寫模式可讓相同邏輯主題 (或佇列) 的作用中複本用於多個命名空間 (和區域) 中,以及讓所有訊息可在所有複本中使用,無論其排入佇列的位置為何。 此模式通常會保留相對於任何發行者的訊息順序。

所有現用模式

如圖所示,此模式通常會依存於服務匯流排主題。 每個應參與複寫配置的命名空間都有一個主題。 每個主題都有一個「複寫訂用帳戶」,用於訊息應複寫到的其他任何主題。 在上圖中,我們只有一對主題,因此各自的另一個主題會有單一複寫訂用帳戶。 在有三個命名空間 {n1, n2, n3} 的案例中,命名空間 n1 中的主題會有兩個複寫訂用帳戶,一個用於 n2 中的對應主題,另一個用於 n3 中的對應主題。

每個複寫訂用帳戶都有一個結合 SQL 篩選運算式 (replicated <> 1) 和 SQL 動作 (set replicated = 1) 的規則。 規則的篩選可確保只有自訂屬性 replication 未設定或沒有值 1 的訊息,才會符合此訂用帳戶的條件,且該動作會隨即在每個選取的訊息上將該屬性設定為值 1。 其結果是,當訊息複製到對應的主題時,將不再符合反向複寫的條件,因此可以避免訊息在複本之間來回傳送。

具有個別規則的訂用帳戶可透過 Azure CLI 輕易新增至任何主題,如下所示。


az servicebus topic subscription rule create --resource-group myresourcegroup \
   --namespace mynamespace --topic-name mytopic \
   --subscription-name replication --name replication \
   --action-sql-expression "set replication = 1" \
   --filter-sql-expression "replication IS NULL"

若要建立佇列的模型,每個主題應限定於所有取用者共用的一個一般訂用帳戶 (而不是複寫訂用帳戶)。

全主動複寫模型會將傳送至任何主題的每個訊息複本放入每個主題中。 這表示您在每個區域中的應用程式程式碼都會看到並處理所有訊息。 此模式適用於將資料共用於多個區域的案例,或通常需要備援處理的情況。 如果只需要像一般佇列那樣每個訊息處理一次,您需考慮使用下列兩種模式之一。

主動-被動複寫

「主動-被動」複寫模式是先前模式的變體,在此模式下,由應用程式只會主動使用其中一個主題 (「主要」) 來傳送和接收訊息,且在主要主題可能變得無法使用或無法連線時,訊息會複寫到次要主題中。

主動/被動模式

此模式與先前模式的主要差異在於,複寫是從主要主題到次要主題的單向複寫。 次要主題永遠不會成為主要主題,但在主要主題暫時無法使用時,將是備用選項。

使用此模式的優點,是會試著盡可能減少重複處理。 在複寫期間,TimeToLive 訊息屬性會設定為複寫訊息的持續時間,以反映主要主題的失敗將導致容錯移轉的預期時間。 例如,如果在您的使用案例中,從主要主題擷取訊息的動作發生問題時,取用者必須在 1 分鐘內切換至次要主題,則在理想情況下,次要主題應該要有您在主要主題中無法存取的所有訊息,但您在問題出現之前已從主要主題處理的訊息,則應愈少愈好。 如果我們在複寫期間將 TimeToLive 設定為該期間的 2 倍,即 2 分鐘 (規則動作中的 set sys.TimeToLive = '0:2:0'),則次要主題將只會保留訊息 2 分鐘,並捨棄較舊的訊息。 這表示,當接收者切換至次要主題時,可以快速讀取並捨棄比最後一個處理的訊息還舊的訊息,然後從尚未檢視的第一個訊息進行處理。 實際的保留期間將取決於特定的使用案例,以及您想要在應用程式中切換至次要主題的速度。 可接受的 TimeToLive 設定介於數秒到數天。

應用程式在使用次要主題時,也可以直接發佈至次要主題,屆時該主題就可作為任何一般主題。 切換至次要主題後,取用者將同時看到複寫的訊息以及直接發佈至次要主題的訊息。 因此,應用程式應該先將發佈切換回主要主題,且仍允許在將取用者切換回次要主題之前清空本機發佈的訊息。 由於複寫會在主要主題再次可用後自動繼續,取用者也會在該期間取得發佈至主要主題的新訊息,但會有較高一些的延遲。

此模式適用於訊息只需處理一次的案例。 應用程式需協同運作以追蹤已從主要主題處理的訊息,因為它會在次要主題的容錯移轉期間尋找重複項目,並且在切換回去時再次尋找重複項目。 重複資料刪除準則最好是應用程式提供的 MessageIdEnqueuedTimeUtc 值也可作為浮水印指標,但應用程式必須允許主要和次要主題之間有一定程度的時鐘漂移 (數秒),如同任何分散式系統一樣。

溢出複寫

「溢出」複寫模式可讓您在多個區域中以「主動/主動」的方式使用多個服務匯流排實體,以因應以下情況:服務匯流排狀況良好,但取用者因擱置的訊息眾多而疲於應付或完全沒有空閒。 其原因可能是支援取用者程序的資料庫變慢或無法使用。 此模式適用於純佇列和主題訂用帳戶。

溢出複寫

如下圖所示,溢出複寫模式會將訊息從佇列或訂用帳戶的相關無效信件佇列複寫至不同命名空間中的成對佇列或主題。

若未發生失敗的狀況,兩個命名空間就會平行使用,每個命名空間分別接收整體訊息流量的某個子集,以及處理該子集的相關取用者。 一旦其中一個取用者開始顯現高失敗率或完全停止,個別訊息最終將因為超過傳遞計數或已過期,而放入無效信件佇列中。 然後,複寫工作會加以取用,並在成對的佇列中將其重新排入佇列,繼而呈現給可能狀況良好的取用者。

如果處理必須在特定期限內執行,則應為佇列和/或訊息適當設定 TimeToLive,讓溢出次要主題仍可及時進行處理,例如,TimeToLive 可設定為容許時間的一半。

如同全主動模式,應用程式可在訊息中新增指標,指出訊息是否已複寫一次,使其不會在成對的佇列之間來回傳送,而是發布到輔助佇列 (此為複合模式的無效信件佇列)。

此模式適用於以下案例:首要考量為防範取用者或其仰賴的資源出現可用性問題,以及將流量尖峰重新分配於其中一個成對的佇列上。 此外,也可在取用者同時從這兩個佇列讀取時用來防止其中一個命名空間變得無法使用,但 TimeToLive 到期所施加的複寫延遲,可能導致該時間範圍內的訊息滯留在無法使用的命名空間中。

延遲最佳化

主題可用來將資訊散發給多個取用者。 在某些情況下,特別是廣佈於各地理位置的取用者,將主題中的訊息複寫到更靠近取用者的次要命名空間中的主題,可能有其效益。

延遲最佳化

例如,在區域性的大陸中樞之間共用資料時,僅在中樞之間傳輸資訊一次,而讓取用者從這些中樞取得其資料複本,會較有效率。

複寫傳輸可分批完成,此時取用者通常會逐一取得和處理訊息。 例如,假設北美洲與歐洲之間有 100 毫秒的基本網路延遲,相較於相同區域中的實體,在兩次往返於遠端實體以取得和處理訊息的過程中,處理每個訊息需要多花 200 毫秒的時間。

驗證、減少和擴充

訊息可由您自己的解決方案外部的用戶端提交至服務匯流排佇列或主題中。

驗證、減少、擴充

對於這類訊息,可能需要檢查是否符合給定的結構描述,以及檢查是否有不符合規範的訊息要捨棄或放入無效信件佇列中。 有些訊息可能需要省略資料以降低複雜度,有些則可能需要根據參考資料查閱來新增資料予以擴充。 作業可使用複寫工作中的自訂功能來執行。

串流至佇列複寫

Azure 事件中樞是用來處理大量傳入事件量的理想解決方案。 不過,事件中樞或類似的引擎 (例如 Apache Kafka) 皆未提供服務管理的競爭性取用者模型,讓多個取用者能夠並行處理來自相同來源的訊息,而不會有重複處理的風險,且最終在處理完這些訊息後能予以處置。

整合

佇列複寫的資料流會將單一事件中樞分割區的內容或完整事件中樞的內容傳輸至服務匯流排佇列中,其後,即可從該處以交易方式安全地與競爭的取用者一起處理訊息。 此複寫也可讓您對這些訊息使用所有其他服務匯流排功能,包括依主題進行路由和以工作階段為基礎的分離信號。

彙總和正規化

全域解決方案通常是由大多獨立的區域性使用量所組成,包括擁有本身的處理功能,但超區域和全域觀點將需要資料整合,因此需要集中彙整在個別區域性使用量中評估的相同訊息資料,以取得本機觀點。

彙總

正規化是彙總案例的變體,其中有兩個以上的傳入訊息序列會攜帶相同類型的資訊 (但具有不同的結構或不同的編碼),且訊息必須在轉碼或轉換後才能使用。

正規化也可能包含加密工作,例如解密端對端加密的承載,以及針對下游取用者對象使用不同的金鑰和演算法將其重新加密。

分割和路由

服務匯流排主題及其訂用帳戶規則常用來篩選特定對象的訊息串流,讓該對象隨後從訂用帳戶中取得篩選的集合。

分割中

在全域系統中,這些訊息的對象是全域分布的,或是屬於不同的應用程式,可以使用複寫將訊息從這類訂用帳戶傳輸至從中取用訊息的不同命名空間中的佇列或主題。

Azure Functions 中的複寫應用程式

針對您想要設定和執行的複寫工作,實作上述模式需要可調整且可靠的執行環境。 在 Azure 上,最適用於無狀態工作的執行階段環境是 Azure Functions

Azure Functions 可在 Azure 受控識別下執行,讓複寫工作可與來源和目標服務的角色型存取控制規則整合,而無需您依據複寫路徑管理秘密。 對於需要明確認證的複寫來源和目標,Azure Functions 可在 Azure Key Vault 內受到嚴密存取控制的儲存體中保存這些認證的設定值。

Azure Functions 還可讓複寫工作直接與 Azure 虛擬網路和所有 Azure 傳訊服務的服務端點整合,而且可以隨時與 Azure 監視器整合。

最重要的是,Azure Functions 具有預建、可調整的觸發程序和輸出繫結 (適用於 Azure 事件中樞Azure IoT 中樞Azure 服務匯流排Azure 事件方格,以及 Azure 佇列儲存體),以及適用於 RabbitMQApache Kafka 的自訂延伸模組。 大部分的觸發程序會根據記載的計量,將同時執行的執行個體數目擴增或縮減,以動態方式適應輸送量需求。

使用 Azure Functions 取用方案,預建的觸發程序甚至可以在沒有任何訊息可供複寫時縮減至零,這表示您無須支付任何成本,即可將設定保持備妥狀態,以再次擴增。 使用取用方案的主要缺點是,從這個狀態「喚醒」複寫工作時的延遲明顯高於基礎結構保持執行中狀態的裝載方案。

相較之下,傳訊和事件的最常見複寫引擎 (例如 Apache Kafka 的 MirrorMaker) 會要求您提供裝載環境,並自行調整複寫引擎。 這包括設定和整合安全性和網路功能,以及協助監視資料的流程,然後您仍然沒有機會將自訂複寫工作插入流程中。

使用 Azure Logic Apps 進行複寫工作

使用 Functions 執行複寫的非撰寫程式碼替代方案是改用 Logic Apps。 Logic Apps 具有服務匯流排的預先定義複寫工作。 這些都有助於設定不同執行個體之間的複寫,並可調整以進一步自訂。

後續步驟

在本文中,我們探索了一系列的同盟模式,並說明了 Azure Functions 在 Azure 中作為事件和傳訊複寫執行階段的角色。

接下來,您應了解如何使用 Azure Functions 來設定複寫器應用程式,然後如何在事件中樞與其他各種事件和傳訊系統之間複寫事件流程: