將大量訊息承載資料儲存在外部資料存放區中,並僅透過訊息系統傳送其參照。 接收應用程式會提供稱為 claim check的參考標記,以便在需要處理時取回大型有效載荷。 這種方式讓工作負載能夠傳輸大量承載資料,而無需將其儲存在訊息系統中。
內容和問題
傳統訊息系統優化以管理大量小訊息,且常限制其可處理的訊息大小。 大型訊息不僅有可能超過大小限制,當訊息系統儲存訊息時,還可能降低系統效能。
以下限制使得透過訊息系統傳輸內嵌酬載不足以滿足需求:
因大小限制而遭拒。 訊息系統會拒絕超過設定上限的訊息。
經紀人資源壓力。 在中介中儲存大型有效載荷,會消耗不成比例的記憶體與磁碟,相較於中介者用來路由和傳遞訊息所需的元資料。 這種資源消耗會與系統中其他訊息所需的資源互相爭奪。
吞吐量下降。 較大的訊息會增加每次操作的序列化、傳輸與反序列化時間。
成本飆升。 部分訊息系統依訊息大小、層級或容量單位收費。 在線傳輸大型有效負載可能會將工作負載推向較高成本層級或容量分配。
解決方案
Claim Check 模式將有效載荷儲存與訊息傳遞分離。 發送應用程式會將完整的有效載荷寫入外部資料儲存,並透過訊息系統傳送該有效載荷的參考。 傳訊系統永遠不會看到或儲存承載。 接收應用程式會利用該參考,直接從資料儲存庫擷取酬載。 參考是接收應用程式必須解析的識別碼。
模式遵循以下序列:
- 傳送應用程式會產生承載資料。
- 傳送應用程式會將有效載荷儲存在外部資料儲存中。
- 儲存成功後,傳送應用程式會產生已儲存有效載荷的參考,並將其作為 Claim Check 訊息發布到訊息系統。
- 接收應用程式會擷取訊息並讀取宣稱檢查標記。
- 接收應用程式使用令牌從資料儲存庫取得有效載荷。
- 接收端應用程式會處理承載資料。
訊息系統只會處理小型 claim check 訊息,因而可避免因訊息過大而遭拒收,以及避免耗用資源來傳輸及保存大型訊息承載資料。 外部資料儲存庫對有效載荷套用存取控制與生命週期政策,獨立於訊息系統之外。
問題和考慮
決定如何實作此模式時,請考慮下列幾點:
有效載荷生命週期所有權。 定義哪個元件擁有有效載荷刪除權,以及該元件如何判斷該有效載荷不被需要。 協調訊息過期與有效載荷保留,避免有效的理賠檢查指向已刪除的資料。
有條件申請。 決定是讓所有訊息都使用 claim check,還是針對每則訊息分別決定是否使用 claim check。 如果是條件式,請確保結構中明確定義有效載荷是線上還是外部。
代幣與儲存安全。 不要在理賠檢查時嵌入安全令牌。 讓授權維持為生產者或消費者系統與資料存放區之間的獨立互動。 如果你的解決方案需要明確授予使用者暫時性存取權限,請改用 代客泊車鑰匙模式。
有效載重與代幣一致性。 有效載荷寫入與令牌發佈發生在不同的系統中,並非在同一個原子交易中。 若在有效載荷寫入後但標記發佈前失敗,可能會使有效載荷成為孤兒。 若某個代幣在其酬載可供擷取之前就已發布,可能意味著消費者會收到他們無法解析的參照。 只有在有效載荷寫入成功後才發布該令牌。 由於重試可能會不只一次傳遞相同的 claim check,請使用 冪等消費者模式 安全地處理重複項目。
酬載完整性。 當使用方必須驗證訊息承載資料的完整性時,請在訊息中加入內容雜湊值或數位簽章。 針對不一致情況定義處理程序,例如拒絕酬載、重新擷取,或將訊息轉送以進行調查。
有效載荷可用性與耐用性。 外部資料儲存必須在接收應用程式需要檢索有效載荷的整個期間保持可用且耐用。 若商店發生故障或資料遺失,持有有效代幣的消費者無法取回有效載荷,訊息處理會停滯。
檢索跳延遲。 此模式相較於內嵌訊息傳遞增加了更多網路行程。 接收應用程式必須呼叫外部資料儲存庫取得有效載荷,才能開始處理。
框架提供的理賠查核支援。 善用訊息匯流排 SDK 所提供的功能。 例如,NServiceBus 有 DataBus 功能,可以自動化有效載荷儲存與檢索。
使用此模式的時機
當下列情況時,請使用此模式:
訊息有效載荷經常超過 訊息系統所支援的最大訊息大小。 將有效載荷卸載至外部資料儲存,並僅傳送輕量級權利要求檢查令牌,可避免大小限制的拒絕。
大型訊息會消耗不成比例的經紀人資源。 大型訊息會影響訊息系統效能,因為會增加序列化與傳輸時間,或降低所有共享訊息系統的生產者與消費者的吞吐量。
有效載荷包含敏感資訊 ,這些資訊不應被訊息系統或中介元件(如佇列監控工具)看到。 可將圖案套用於整個有效載荷,或僅適用於敏感部分。 將敏感內容存放在具備專用存取控制的安全資料庫中,以防其進入訊息路徑。
訊息具有複雜的路由,並有重複序列化。 訊息會經過多個執行序列化、解序列化、加密或解密的路由元件。 只需透過中介傳送一個小標記,即可消除每跳重複處理完整有效載荷並降低累積延遲。
在下列情況下,此模式可能不適用:
延遲敏感度比有效載荷大小的考量更重要。 要求生產者與消費者之間具備盡可能最低端對端延遲的工作負載,可能無法容忍因儲存及擷取承載資料而增加的網路躍點。 如果訊息能在不超過容量或效能限制的情況下進行內嵌傳送,直接傳送會更簡單且更快。
你可以選擇支援該承載資料大小的傳輸方式或層級。 當有效載荷維持在傳輸支援的限制內,且不會造成不可接受的吞吐量或延遲時,就將有效載荷串聯傳送,以避免外部儲存依賴。 例如,Azure 服務匯流排 Premium 層支援最高 100 MB 的進階訊息佇列協定(AMQP)訊息。 訊息盡量保持小,因為大訊息會降低吞吐量並增加延遲。
兩個系統間的協調是不可能的。 這種模式需要兩個獨立系統間的協調。 理賠檢查值必須以接收系統能理解的方式撰寫,且其格式可能需要隨時間調整。
Alternatives
請將以下方法視為此模式的替代方案:
減少線上有效載荷的尺寸。 壓縮可減少重複文字或二進位酬載,而更精簡的序列化器則可降低訊息負荷。 當減少的有效載荷舒適地符合傳輸限制,且每位生產者與消費者都能使用相同的壓縮與序列化格式時,選擇此方法。
以自然的方式拆分並彙整負載資料。 當消費者可以獨立處理區塊或在交付後重新組合時,將大型有效載荷分割成一連串較小的訊息。 此方法將資料保留在訊息系統中,但同時增加了排序、關聯性、重複處理及重組等需求。 欲了解更多資訊,請參閱企業整合模式中的 分流 器與 聚合器 模式。
工作負載設計
評估如何在工作負載設計中使用理賠檢查模式,以達成Azure Well-Architected框架支柱所涵蓋的目標與原則。 下表提供有關此模式如何支援各支柱目標的指引。
| 支柱 | 此模式如何支援支柱目標 |
|---|---|
| 可靠性設計決策有助於使工作負載具備彈性抵抗故障,並確保其在故障後能夠完全復原。 | 訊息系統能提供持久的傳遞、高可用性與災難復原,但通常無法提供專用資料儲存的有效載荷層級資料保護與復原能力,如版本控制、備份、點點還原或獨立複製。 將有效載荷分開儲存,可以根據有效載荷回收需求選擇並配置這些功能。 - RE:03 失敗模式分析 - RE:09 災害復原 |
| 安全性 設計決策有助於確保 工作負載數據和系統的機密性、 完整性和 可用性 。 | 理賠檢查模式能從訊息中擷取敏感資料並儲存在安全的資料庫中。 此配置能加強存取控制,只有意圖使用敏感資料的服務才能存取。 此模式也會將這些資料隱藏於無關服務之外,例如用於佇列監控的服務。 - SE:03 數據分類 - SE:04 分割處理 |
| 成本最佳化著重於維持和改善工作負載的投資報酬率。 | 訊息系統通常會對訊息大小設限,而增加大小限制通常是優先功能。 縮小訊息主體大小,或許能讓你使用更便宜的訊息解決方案。 將酬載儲存、網路傳輸和清理處理所增加的成本納入考量。 - CO:07 元件成本 - CO:09 流程成本 |
| 效能效率 可以通過優化伸縮性、數據傳輸和程式碼執行來有效地滿足需求。 | 理賠檢查模式透過更有效管理大型訊息,提升發送、接收及訊息系統的效率。 它減少發送給訊息系統的訊息大小,並確保接收應用程式僅在需要時存取大型訊息。 - PE:05 擴展和分區 - PE:12 持續效能優化 |
如果此模式在一個支柱內部引入取捨,請將它們與其他支柱的目標進行考量。
Examples
本節連結至 GitHub Claim-check 雲端模式範例,展示 Azure 服務如何實作 Claim Check 模式。 每個範例都使用 Azure Blob 儲存體 作為外部資料儲存,並搭配不同的 Azure 訊息系統。 範例 1 到 3 在 Azure 事件方格 通知中使用 blob URL 作為申請檢查。 範例 4 使用由傳送應用程式發佈的自訂宣告檢查。
在範例1到3中:
- 發送應用程式會將大型有效載荷上傳至 Blob 儲存體。
- 上傳會透過 Event Grid 系統主題觸發
Microsoft.Storage.BlobCreated事件。 - Event Grid 會將通知(包含範例用作聲明檢查的直接 blob URL)導向已設定的訊息系統。
- 接收應用程式(實作為 Azure Functions 函式應用程式或命令列用戶端)會擷取通知、擷取 blob URL,並直接從 Blob 儲存體 下載有效載荷進行處理。
在生產實作中,你會根據表示已完全承諾區塊的操作來篩選事件訂閱,並設計接收端以處理延遲、重複及亂序事件。
範例四採用不同的方法。 發送應用程式不是透過事件網格傳送 Blob 儲存體 通知,而是在將有效載荷上傳至 Blob 儲存體 後,自行建立權利要求檢查。 發送應用程式接著會透過 Apache Kafka 協議,將聲明檢查發布到 Azure 事件中樞 Kafka 端點。 此方法適合已使用 Kafka 相容製作者或需要自訂代幣格式的環境。
下表列出各個範例的訊息系統、Claim Check 發行者、接收應用程式及儲存體相依性。 請選擇每個連結即可在 GitHub 上查看範例程式碼。
| 範例程式碼 | 訊息系統 | 理賠支票出版商 | 接收申請 | 儲存相依關係 |
|---|---|---|---|---|
| 程式代碼範例 1 | Azure 佇列儲存體 | 事件方格 | Functions | Blob 儲存體 |
| 程式代碼範例 2 | 事件中樞 (Azure SDK 透過 AMQP) | 事件方格 | 可執行的命令行用戶端 | 用於承載資料的 Blob 儲存體,以及個別的 Blob 儲存體 檢查點存放區 |
| 程式代碼範例 3 | 服務匯流排 | 事件方格 | Functions | Blob 儲存體 |
| 程式代碼範例 4 | Event Hubs (Apache Kafka 協議) | 可執行的命令行用戶端 | Functions | Blob 儲存體 |
下一步
- 請閱讀企業整合模式中 Claim Check 的權威說明。
- 請參閱 使用宣告檢查模式處理大型 服務匯流排 訊息中的另一種實作。
- 請在 Azure 事件方格、Event Hubs 和 服務匯流排 之間選擇。