他のメッセージ グループの処理をブロックせずに、関連する一連のメッセージを定義された順序で処理します。
コンテキストと問題
多くの場合、アプリケーションでは、増加した負荷に対応するためにスケールアウトできると同時に、受信した順序で一連のメッセージを処理する必要があります。 分散アーキテクチャでは、これらのメッセージを順番に処理することは簡単ではありません。これは、ワーカーが個別に拡張でき、多くの場合、競合コンシューマー パターンを使用してメッセージを個別にプルできるためです。
たとえば、注文追跡システムは、注文とその注文に関連する操作を含む台帳を受け取ります。 これらの操作は、注文を作成したり、注文にトランザクションを追加したり、過去のトランザクションを変更したり、注文を削除するものなどです。 このシステムでは、注文レベルでのみ操作は先入れ先出し (FIFO) 方式で実行する必要があります。 しかし、初期キューは、インターリーブされる可能性がある多くの注文のトランザクションを含む台帳を受け取ります。
解決策
関連するメッセージをキュー システム内のカテゴリにプッシュし、キュー リスナーが 1 つのカテゴリから一度に 1 つずつロックしてプルするようにします。
一般的なシーケンシャルなコンボイパターンは次のようになります。
キューでは、次の図に示すように、異なるカテゴリのメッセージがインターリーブされる場合があります。
問題と注意事項
このパターンの実装方法を決めるときには、以下の点に注意してください。
- カテゴリ/スケール ユニット。 受信メッセージのどのプロパティをスケールアウトできるでしょうか。 注文追跡シナリオでは、このプロパティは注文 ID です。
- スループット。 ターゲット メッセージのスループットはどうでしょうか。 非常に高い場合は、FIFO の要件を再検討する必要があります。 たとえば、開始/終了メッセージを適用し、時刻で並べ替え、バッチを送信して処理することができますか。
- サービス機能。 選択したメッセージ バスでは、キューまたはキューのカテゴリ内のメッセージの 1 つずつの処理が許可されるでしょうか。
- 発展性。 新しいカテゴリのメッセージをシステムに追加するにはどうすればよいでしょうか。 たとえば、上記で説明した台帳システムが特定の顧客であるとします。 新しい顧客をオンボードする必要がある場合、顧客 ID ごとに作業を配分する一連の台帳プロセッサを使用できますか。
- メッセージを送信するときのネットワーク待ち時間が変化するため、コンシューマーが順序どおりにメッセージを受信しない可能性があります。 順序を確認するには、シーケンス番号を使用することを検討してください。 トランザクションの最後のメッセージに、特別な "シーケンスの終了" フラグを含めることもできます。 Spark や Azure Stream Analytics などのストリーム処理テクノロジは、時間枠内でメッセージを順番に処理できます。
このパターンを使用する状況
このパターンは次の状況で使用します。
- 順番に受信し、同じ順序で処理する必要があるメッセージがあります。
- 受信するメッセージは、カテゴリがシステムのスケールの単位になるような方法で "分類" できます。
このパターンが適していないと考えられる状況は次のとおりです。
- 非常に高いスループットのシナリオ (数百万のメッセージ/分または秒) です。これは、FIFO の要件によって、システムで実行できるスケーリングが制限されるためです。
ワークロード設計
設計者は、Azure Well-Architected Framework の柱で説明されている目標と原則に対処するために、ワークロードの設計でどのようにシーケンシャルなコンボイ パターンを使用できるかを評価する必要があります。 次に例を示します。
重要な要素 | このパターンが柱の目標をサポートする方法 |
---|---|
信頼性 設計の決定により、ワークロードが 誤動作 に対して復元力を持ち、障害発生後も完全に機能する状態に 回復 することができます。 | このパターンにより、トラブルシューティングが困難な競合状態、メッセージ処理の衝突、その他誤動作を引き起こす可能性のある不適切な順序のメッセージに対処するための回避策を排除できます。 - RE:02 クリティカルフロー - Re: 07バックグラウンドジョブ |
設計決定と同様に、このパターンで導入される可能性のある他の柱の目標とのトレードオフを考慮してください。
例
Azure では、このパターンは Azure Service Bus メッセージ セッションを使用して実装できます。 コンシューマーの場合、Service Bus ピーク ロック コネクタを備えた Logic Apps または Service Bus トリガーを備えた Azure Functions を使用できます。
前の注文追跡の例では、各元帳メッセージを受信順に処理し、各トランザクションを別のキューに送信して、そのカテゴリが注文 ID に設定されていることを確認します。 このシナリオでは、1 つのトランザクションが複数の注文にまたがることはありません。そのため、コンシューマーは各カテゴリを並行して処理しますが、カテゴリ内では FIFO です。
台帳プロセッサは、最初のキュー内の各メッセージの内容をバッチ解除することによってメッセージを展開します。
台帳プロセッサでは次の処理が行われます。
- 一度に 1 トランザクションずつ台帳を処理します。
- 注文 ID に一致するようにメッセージのセッション ID を設定します。
- 注文 ID に設定されたセッション ID を使用して、各元帳トランザクションをセカンダリ キューに送信します。
コンシューマーはセカンダリ キューをリッスンします。このキューでは、注文 ID が一致するすべてのメッセージをキューから順番に処理します。 コンシューマーはピーク ロック モードを使用します。
スケーラビリティを考慮する場合、台帳キューは主なボトルネックになります。 元帳にポストされたさまざまなトランザクションは、同じ注文 ID を参照できます。 ただし、サーバーレス環境内では、メッセージは台帳の後に、注文数に対して展開する可能性があります。
次のステップ
このパターンを実装するときは、次の情報を参考にしてください。