大きなメッセージ ペイロードを外部データ ストアに格納し、メッセージング システムを介して格納されているペイロードへの参照のみを送信します。 受信アプリケーションは、 要求チェックと呼ばれる参照トークンを提示し、処理が必要な場合に大きなペイロードを取得します。 このアプローチにより、ワークロードは、メッセージング システムに格納することなく、大きなペイロードを転送できます。
コンテキストと問題
従来のメッセージング システムは、大量の小さなメッセージを管理するように最適化されており、多くの場合、処理できるメッセージ サイズを制限します。 大きなメッセージはサイズ制限を超えるリスクがあるだけでなく、メッセージング システムがメッセージを格納するときにシステム のパフォーマンスを低下させる可能性もあります。
次の制約により、メッセージング システムを介したインライン ペイロード転送が不十分になります。
サイズ制限の拒否。 メッセージング システムは、構成された最大値を超えるメッセージを拒否します。
ブローカーリソースの負荷。 ブローカーに大きなペイロードを格納すると、ブローカーがメッセージをルーティングして配信するために必要なメタデータと比較して、不均衡なメモリとディスクが消費されます。 この消費量は、システム内の他のメッセージに必要なリソースと競合します。
スループットの低下。 メッセージが大きいほど、操作ごとのシリアル化、転送、逆シリアル化の時間が長くなります。
コストエスカレーション。 一部のメッセージング システムでは、メッセージ サイズ、レベル、または容量ユニットごとに課金されます。 大規模なペイロードをインラインで送信すると、ワークロードを高コストレベルまたは容量割り当てにプッシュできます。
ソリューション
要求チェック パターンは、ペイロード ストレージをメッセージ配信から分離します。 送信アプリケーションは、完全なペイロードを外部データ ストアに書き込み、メッセージング システムを介してそのペイロードへの参照を送信します。 メッセージング システムでは、ペイロードが表示または格納されることはありません。 受信アプリケーションでは、参照を使用して、データ ストアからペイロードを直接取得します。 参照は、受信側アプリケーションが解決する必要がある識別子です。
パターンは、次のシーケンスに従います。
- 送信アプリケーションによってペイロードが生成されます。
- 送信アプリケーションは、ペイロードを外部データ ストアに保存します。
- 保存が成功すると、送信アプリケーションは格納されているペイロードへの参照を生成し、要求チェック メッセージとしてメッセージング システムに発行します。
- 受信側アプリケーションがメッセージを取得し、要求チェック トークンを読み取ります。
- 受信側アプリケーションは、トークンを使用してデータ ストアからペイロードを取得します。
- 受信側のアプリケーションがペイロードを処理します。
メッセージング システムは、小さな要求チェック メッセージのみを処理するため、メッセージ サイズの拒否が回避され、リソースを使用して大きなメッセージ ペイロードを転送および保持する必要がなくなります。 外部データ ストアは、メッセージング システムに関係なく、アクセス制御とライフサイクル ポリシーをペイロードに適用します。
問題と考慮事項
このパターンを実装する方法を決定するときは、次の点を考慮してください。
ペイロードのライフサイクル管理責任。 ペイロードの削除を所有するコンポーネントと、ペイロードが不要であるとコンポーネントが判断する方法を定義します。 メッセージの有効期限とペイロードの保持期間を調整して、有効な要求チェックで削除されたデータがポイントされないようにします。
条件付きアプリケーション。 すべてのメッセージ要求チェックを行うか、メッセージごとに要求チェックを決定するかを決定します。 条件付きである場合は、ペイロードがインラインか外部かをスキーマで定義します。
トークンと格納のセキュリティ。 要求チェックの一部としてセキュリティ トークンを埋め込まない。 プロデューサーまたはコンシューマー システムとデータ ストアの間の独立した相互作用として承認を残します。 ソリューションでコンシューマーに一時的なアクセスを明示的に許可する必要がある場合は、代わりに バレット キー パターン を使用します。
ペイロードとトークンの一貫性。 ペイロードの書き込みとトークンの発行は別々のシステムで行われ、1 つのアトミック トランザクションには含まれません。 ペイロードの書き込み後、トークンの発行前に失敗すると、ペイロードが孤立したままになります。 ペイロードを取得できるようになる前に発行されたトークンは、コンシューマーが解決できない参照を受け取ることにつながる可能性があります。 ペイロードの書き込みが成功した後にのみトークンを発行します。 再試行により同じクレーム チェックが複数回配信される可能性があるため、冪等コンシューマー パターンを使用して重複を安全に処理できるようにします。
ペイロードの整合性。 コンシューマーがペイロードの整合性を確認する必要がある場合は、メッセージにコンテンツ ハッシュまたはデジタル署名を含めます。 ペイロードの拒否、取得の再試行、調査のためにメッセージのルーティングなど、不一致のプロトコルを定義します。
ペイロードの可用性と持続性。 外部データ ストアは、受信アプリケーションがペイロードを取得する必要がある期間、使用可能で永続的なままである必要があります。 ストアで障害やデータ損失が発生した場合、有効なトークンを保持しているコンシューマーはペイロードとメッセージ処理ストールを取得できません。
検索ホップのレイテンシ。 このパターンでは、インライン メッセージ配信と比較して追加のネットワーク トリップが追加されます。 アプリケーションを受信するには、処理を開始する前に、外部データ ストアを呼び出してペイロードを取得する必要があります。
フレームワークによって提供される要求チェックのサポート。 メッセージ バス SDK が提供する機能を使用します。 たとえば、NServiceBus には、ペイロードの格納と取得を自動化できる DataBus 機能があります。
このパターンを使用する場合
このパターンは次の状況で使用します。
メッセージ ペイロードは、メッセージング システムがサポートする最大メッセージ サイズを定期的に超えています 。 ペイロードを外部データ ストアにオフロードし、軽量の要求チェック トークンのみを送信すると、サイズ制限の拒否が回避されます。
大きなメッセージは、不均衡なブローカー リソースを消費します。 大きなメッセージは、シリアル化と転送時間の増加、またはメッセージング システムを共有するすべてのプロデューサーとコンシューマーのスループットの低下によって、メッセージング システムのパフォーマンスに影響します。
ペイロードには、 メッセージング システムやキュー監視ツールなどの中間コンポーネントには表示されない機密情報が含まれています。 パターンをペイロード全体に適用するか、その機密性の高い部分にのみ適用します。 機密性の高いコンテンツをセキュリティで保護されたデータ ストアに格納し、専用のアクセス制御を使用して、メッセージング パスから保護します。
メッセージには、シリアル化を繰り返す複雑なルーティングがあります。 メッセージは、シリアル化、逆シリアル化、暗号化、または復号化を実行する複数のルーティング コンポーネントを走査します。 各ホップでペイロード全体の繰り返し処理を排除し、累積待機時間を短縮するために、中継局を介して小さなトークンのみを送信します。
このパターンは、次の場合に適さない場合があります。
レイテンシの重要性は、ペイロードサイズに関する懸念を上回ります。 プロデューサーとコンシューマーの間で可能な限り短いエンド ツー エンドの待機時間を必要とするワークロードでは、ペイロードのストレージと取得のために追加されたネットワーク ホップが許容されない場合があります。 サイズやパフォーマンスの制限を超えずにメッセージをインラインで配信できる場合、直送はより簡単で高速です。
ペイロード サイズをサポートするトランスポートまたは層を選択できます。 ペイロードがトランスポートのサポートされている制限内に留まり、許容できないスループットや待機時間が作成されない場合は、外部ストアの依存関係を回避するためにインラインで送信します。 たとえば、Azure Service Bus Premium レベルでは、最大 100 MB の Advanced Message Queuing Protocol (AMQP) メッセージがサポートされます。 メッセージが大きいとスループットが低下し、待機時間が長くなるため、メッセージはできるだけ小さくしてください。
2 つのシステム間で調整することはできません。 このパターンには、2 つの独立したシステム間の調整が必要です。 要求チェックの値は、受信側システムが理解できるように書き込む必要があり、その形式を時間の経過と同時に調整する必要がある場合があります。
代替案
このパターンの代替手段として、次の方法を検討してください。
インライン ペイロード サイズを小さくします。 圧縮により、繰り返し発生するテキストまたはバイナリ ペイロードが減り、シリアライザーのコンパクト化によってメッセージのオーバーヘッドが軽減されます。 制限されたペイロードがトランスポート制限内に快適に収まり、すべてのプロデューサーとコンシューマーが同じ圧縮およびシリアル化形式を使用できる場合は、この方法を選択します。
ペイロードを自然に分割して集計します。 コンシューマーがチャンクを個別に処理したり、配信後に再構成したりできる場合は、大きなペイロードを一連の小さなメッセージに分割します。 この方法では、データがメッセージング システムに保持されますが、シーケンス処理、相関関係、重複処理、再組み立て要件が追加されます。 詳細については、「Enterprise Integration Patterns の Splitter および アグリゲーター パターン」を参照してください。
ワークロード設計
ワークロードの設計で要求チェック パターンを使用して、Azure Well-Architected Framework の柱で説明されている目標と原則に対処する方法を評価します。 次の表は、このパターンが柱の目標をサポートする方法に関するガイダンスを示しています。
| 柱 | このパターンが柱の目標をサポートする方法 |
|---|---|
| 信頼性設計の決定は、ワークロードが誤動作に対して回復性を持ち、障害後に完全に復旧するのに役立ちます。 | メッセージング システムは永続的な配信、高可用性、ディザスター リカバリーを提供できますが、通常、バージョン管理、バックアップ、ポイントインタイム リストア、独立したレプリケーションなど、専用データ ストアのペイロード レベルのデータ保護と回復機能は提供されません。 ペイロードを個別に格納すると、ペイロードの回復要件に基づいてこれらの機能を選択して構成できます。 - RE: 03 障害モード分析 - RE:09 災害復旧 |
| セキュリティ設計の決定により、ワークロードのデータとシステムの機密性、整合性、および可用性が確保されます。 | 要求チェック パターンでは、メッセージから機密データを抽出し、セキュリティで保護されたデータ ストアに格納できます。 この設定により、より厳密なアクセス制御が可能になり、機密データを使用するサービスのみがアクセスできるようになります。 このパターンでは、キューの監視に使用されるサービスなど、関連のないサービスからもこのデータが非表示になります。 - SE:03 データ分類 - SE:04 セグメンテーション |
| コスト最適化は、ワークロードの投資収益率の維持と改善に重点を置いています。 | メッセージング システムでは、多くの場合、メッセージ サイズに制限が課され、サイズ制限の引き上げは多くの場合、プレミアム機能です。 メッセージ本文のサイズを小さくすると、より安価なメッセージング ソリューションを使用できる場合があります。 ペイロード ストレージ、ネットワーク転送、クリーンアップ処理の追加コストを考慮します。 - CO:07 コンポーネントコスト - CO:09 フローコスト |
| パフォーマンスの効率化 は、スケーリング、データ、コード回を最適化することによって、ワークロードが 効率的に需要を満たすのに役立ちます。 | 要求チェック パターンでは、大きなメッセージをより効果的に管理することで、送信、受信、およびメッセージング システムの効率が向上します。 これにより、メッセージング システムに送信されるメッセージのサイズが縮小され、受信アプリケーションが必要なときにのみ大きなメッセージにアクセスできるようになります。 - PE:05 スケーリングとパーティショニング - PE: 12 パフォーマンスの継続的な最適化 |
このパターンによって柱内にトレードオフが生じる場合は、他の柱の目標に照らして検討してください。
Examples
このセクションでは、Azure サービスが要求チェック パターンを実装する方法を示す、GitHub要求チェック クラウド パターンの例にリンクします。 各例では、外部データ ストアとしてAzure Blob Storageを使用し、別のAzure メッセージング システムとペアリングします。 サンプル 1 ~ 3 では、Azure Event Grid通知の BLOB URL を要求チェックとして使用します。 サンプル 4 では、送信アプリケーションが発行するカスタム要求チェックを使用します。
サンプル1~3では:
- 送信アプリケーションは、大きなペイロードをBlob Storageにアップロードします。
- アップロードは、Event Grid システム トピックを介して
Microsoft.Storage.BlobCreatedイベントをトリガーします。 - Event Grid は、例が要求チェックとして使用する直接 BLOB URL を含む通知を、構成されたメッセージング システムにルーティングします。
- Azure Functions関数アプリまたはコマンド ライン クライアントとして実装された受信側アプリケーションは、通知を取得し、BLOB URL を抽出し、処理のためにBlob Storageからペイロードを直接ダウンロードします。
運用環境の実装では、完全にコミットされたブロック BLOB を示す操作によってイベント サブスクリプションをフィルター処理し、遅延、重複、および順序外のイベントを処理するようにレシーバーを設計します。
サンプル 4 では、別の方法を使用します。 送信アプリケーションは、Event Grid を介してBlob Storage通知をルーティングする代わりに、ペイロードをBlob Storageにアップロードした後に要求チェックを構築します。 次に、送信側アプリケーションは、Apache Kafka プロトコルを使用して、Azure Event Hubs Kafka エンドポイントに要求チェックを発行します。 このアプローチは、Kafka と互換性のあるプロデューサーを既に使用しているか、カスタム トークン形式を必要とする環境に適しています。
次の表に、メッセージング システム、要求チェックの発行元、アプリケーションの受信、ストレージの依存関係を含む各例を示します。 各リンクを選択して、GitHubのコード例を表示します。
| サンプル コード | メッセージング システム | クレームチェック パブリッシャー | アプリケーションの受信 | ストレージの依存関係 |
|---|---|---|---|---|
| コード例 1 | Azure Queue Storage | Event Grid | Functions | Blob Storage |
| コード例 2 | Event Hubs (AMQP 経由のAzure SDK) | Event Grid | 実行可能なコマンドライン クライアント | ペイロード用の Blob Storage と、別個の Blob Storage チェックポイント ストア |
| コード例 3 | Service Bus | Event Grid | Functions | Blob Storage |
| コード例 4 | Event Hubs (Apache Kafka プロトコル) | 実行可能なコマンドライン クライアント | Functions | Blob Storage |
次のステップ
- Claim Check の Enterprise Integration Patterns における正式な説明をお読みください。
- 「要求チェック パターンを使用した大規模なService Bus メッセージの処理」の別の実装を確認します。
- Azure Event Grid、Event Hubs、Service Busから選択します。