クレーム チェック パターン

大きいメッセージを要求チェックとペイロードに分割します。 要求チェックはメッセージング プラットフォームに送信し、ペイロードは外部サービスに格納します。 このパターンを使用して大きいメッセージを処理すると、メッセージ バスやクライアントで大きな負荷や速度の低下が発生するのを防ぐことができます。 また、通常はストレージの方がメッセージング プラットフォームで使用されるリソース ユニットより安いので、このパターンはコストの削減にも役立ちます。

このパターンは参照ベースのメッセージングとも呼ばれ、もともとは Gregor Hohpe と Bobby Woolf の著作『Enterprise Integration Patterns (エンタープライズ統合パターン) 』で 説明されていたものです。

コンテキストと問題

メッセージング ベースのアーキテクチャは、ある時点で大きいメッセージを送信、受信、操作できるようになる必要があります。 このようなメッセージには、画像 (MRI スキャンなど)、サウンド ファイル (コール センターの呼び出しなど)、テキスト ドキュメント、任意のサイズのあらゆる種類のバイナリ データなど、何でも含まれる可能性があります。

このような大きいメッセージをメッセージ バスに直接送信することは、より多くのリソースと帯域幅を消費する必要があるため、推奨されません。 また、通常、メッセージング プラットフォームは多数の小さいメッセージを処理するように微調整されているため、大きいメッセージではソリューション全体が遅くなることがあります。 また、ほとんどのメッセージング プラットフォームにはメッセージ サイズに制限があるので、大きいメッセージではこれらの制限を回避する必要もあります。

解決策

メッセージのペイロード全体を、データベースなどの外部サービスに格納します。 格納されているペイロードへの参照を取得し、メッセージ バスにはその参照だけを送信します。 参照は、荷物を受け取るための預かり証 (クレーム チェック) のように、パターンの名前として機能します。 その特定のメッセージの処理に関心のあるクライアントは、必要に応じて、入手した参照を使用してペイロードを取得できます。

クレーム チェック パターンの図

問題と注意事項

このパターンの実装方法を決めるときには、以下の点に注意してください。

  • メッセージをアーカイブする必要がない場合は、使用後にメッセージ データを削除することを検討してください。 BLOB ストレージは比較的安価ですが、期間が長くなれば、特に大量のデータがある場合、ある程度のコストがかかります。 メッセージの削除は、メッセージを受信して処理するアプリケーションによって同期的に、または独立した専用プロセスによって非同期的に、実行できます。 非同期的な方法では、受信側アプリケーションのスループットとメッセージ処理パフォーマンスに影響を与えずに、古いデータが削除されます。

  • メッセージの格納と取得では、若干のオーバーヘッドと待機時間が余分に発生します。 メッセージのサイズがメッセージ バスのデータ制限を超えた場合にのみこのパターンを使用するロジックを、送信側アプリケーションに実装することができます。 小さいメッセージの場合はパターンはスキップされます。 このアプローチでは、条件付きの要クレーム チェック パターンになります。

このパターンを使用する状況

選択されているメッセージ バス テクノロジでサポートされているメッセージ制限にメッセージが適合できない場合は常に、このパターンを使用する必要があります。 たとえば、現在、Event Hubs には 256 KB (Basic レベル) の制限がありますが、Event Grid では 64 KB のメッセージしかサポートされていません。

読み取りを許可されたサービスだけがペイロードにアクセスできるようにする必要がある場合も、パターンを使用できます。 ペイロードを外部リソースにオフロードすることで、より厳密な認証と承認の規則を実施し、ペイロードに機密データが格納されている場合にセキュリティを適用することができます。

Azure では、さまざまな方法とテクノロジを使用してこのパターンを実装することができますが、2 つの主なカテゴリがあります。 どちらの場合も、受信側が、要求チェックを読み取り、それを使用してペイロードを取得する責任を持ちます。

  • クレームチェックの自動生成。 この方法では、Azure Event Grid を使用して、自動的に要求チェックを生成し、メッセージ バスにプッシュします。

  • クレームチェックの手動生成。 この方法では、ペイロードを管理する責任は送信側にあります。 送信側は、適切なサービスを使用してペイロードを格納し、要求チェックを取得または生成して、メッセージ バスに要求チェックを送信します。

Event Grid はイベント ルーティング サービスであり、最大 24 時間の構成可能な時間内にイベントの配信が試みられます。 その後、イベントは破棄されるか配信不能にされます。 イベント ペイロードをアーカイブしたり、イベント ストリームを再生したりする必要がある場合は、Event Grid サブスクリプションを Event Hubs または Queue storage に追加できます。そこでは、メッセージを長期間保持でき、メッセージのアーカイブがサポートされています。 Event Grid メッセージの配信と再試行および配信不能の構成の微調整については、「配信不能と再試行に関する方針」をご覧ください。

Blob Storage と Event Grid によるクレームチェックの自動生成

この方法では、送信側が指定された Azure Blob Storage コンテナーにメッセージ ペイロードをドロップします。 Event Grid により、自動的にタグ/参照が生成されて、Azure Storage キューなどのサポートされているメッセージ バスに送信されます。 受信側は、キューをポーリングし、メッセージを取得した後、格納されている参照データを使用して Blob Storage から直接ペイロードをダウンロードできます。

同じ Event Grid メッセージを、Azure Functions で直接使用できます。メッセージ バスを経由する必要はありません。 この方法では、Event Grid と Functions 両方のサーバーレスの性質を最大限に利用します。

この方法のコード例については、こちらをご覧ください。

Event Grid と Event Hubs

前の例と同様に、ペイロードが Azure BLOB コンテナーに書き込まれると、Event Grid によって自動的にメッセージが生成されます。 ただし、この例では、メッセージ バスは Event Hubs を使って実装されます。 クライアントは、それ自体を登録して、イベント ハブに書き込まれたメッセージのストリームを受信できます。 イベント ハブは、メッセージをアーカイブするように構成することもでき、これにより、Apache Spark、Apache Drill、または利用可能な任意の Avro ライブラリなどのツールを使用してクエリ可能な Avro ファイルとして使用できるようになります。

この方法のコード例については、こちらをご覧ください。

Service Bus での要求チェックの生成

このソリューションでは特定の Service Bus プラグイン ServiceBus.AttachmentPlugin を利用することにより、クレームチェック ワークフローの実装が容易になります。 プラグインでは、メッセージの本文が、メッセージ送信時に Azure Blob Storage に格納される添付ファイルに変換されます。

using ServiceBus.AttachmentPlugin;
...

// Getting connection information
var serviceBusConnectionString = Environment.GetEnvironmentVariable("SERVICE_BUS_CONNECTION_STRING");
var queueName = Environment.GetEnvironmentVariable("QUEUE_NAME");
var storageConnectionString = Environment.GetEnvironmentVariable("STORAGE_CONNECTION_STRING");

// Creating config for sending message
var config = new AzureStorageAttachmentConfiguration(storageConnectionString);

// Creating and registering the sender using Service Bus Connection String and Queue Name
var sender = new MessageSender(serviceBusConnectionString, queueName);
sender.RegisterAzureStorageAttachmentPlugin(config);

// Create payload
var payload = new { data = "random data string for testing" };
var serialized = JsonConvert.SerializeObject(payload);
var payloadAsBytes = Encoding.UTF8.GetBytes(serialized);
var message = new Message(payloadAsBytes);

// Send the message
await sender.SendAsync(message);

Service Bus のメッセージは、クライアントがサブスクライブできる通知キューとして機能します。 コンシューマーがメッセージを受信すると、プラグインによって Blob Storage から直接メッセージ データを読み取ることができるようになります。 その後、さらにメッセージを処理する方法をお客様が選択できます。 この方法の利点は、クレームチェックのワークフローが送信側と受信側から抽象化されることです。

この方法のコード例については、こちらをご覧ください。

Kafka でのクレームチェックの手動生成

この例では、Kafka クライアントによって、ペイロードが Azure Blob Storage に書き込まれます。 その後、Kafka 対応の Event Hubs を使用して通知メッセージが送信されます。 コンシューマーはメッセージを受信し、Blob Storage からペイロードにアクセスできます。 この例では、異なるメッセージング プロトコルを使用して、Azure にクレーム チェック パターンを実装する方法を示します。 たとえば、既存の Kafka クライアントをサポートする必要があるような場合です。

この方法のコード例については、こちらをご覧ください。

次のステップ

  • 大きいメッセージを処理するための別のパターンとして、分割集約があります。