コレオグラフィ パターン

Azure Event Grid
Azure Service Bus

中央の制御ポイントに依存するのではなく、システムの各コンポーネントが、ビジネス トランザクションのワークフローに関する意思決定プロセスに参加するようにします。

コンテキストと問題

マイクロサービス アーキテクチャでは、クラウドベースのアプリケーションを複数の小さなサービスに分割し、それらのサービスが連携して、ビジネス トランザクションをエンドツーエンドで処理することがよくあります。 サービス間の結合を弱くするために、各サービスは 1 つのビジネス操作を担当します。 開発の高速化、コード ベースの縮小、スケーラビリティなどの利点があります。 ただし、効率的でスケーラブルなワークフローの設計は難しく、複雑なサービス間通信が必要になることがよくあります。

サービスは、明確に定義された API を使用して、互いに通信します。 1 つのビジネス操作の結果として、すべてのサービス間で複数のポイントツーポイント呼び出しが発生する可能性もあります。 通信の一般的なパターンは、オーケストレーターとして機能する集中化されたサービスを使用するというものです。 すべての受信要求を確認し、それぞれのサービスに操作を委任します。 その過程で、ビジネス トランザクション全体のワークフローも管理します。 各サービスは操作を完了するだけであり、ワークフロー全体は認識しません。

オーケストレーター パターンはサービス間のポイントツーポイント通信を削減しますが、オーケストレーターと、ビジネス トランザクションの処理に参加する他のサービスとの間の密接な結合に起因するいくつかの欠点があります。 タスクを順番に実行するために、オーケストレーターには各サービスの責任に関する一定の領域知識が必要です。 サービスを追加または削除する場合、既存のロジックが壊れるため、通信パスの一部を再設計する必要があります。 適切に設計されたオーケストレーターを使用すれば、ワークフローの構成や、サービスの追加または削除が簡単に行えますが、そのような実装は複雑であり、メンテナンスが困難です。

中央のオーケストレーターを使用して要求を処理する

解決策

中央のオーケストレーターに依存するのではなく、業務をいつどのように処理するかを各サービスで決定できます。

コレオグラフィを実装する 1 つの方法は、非同期メッセージング パターンを使用してビジネス操作をコーディネートすることです。

コレオグラファーを使用して要求を処理する

クライアント要求はメッセージ キューにメッセージを発行します。 メッセージが到着すると、そのメッセージに関心のあるサブスクライバーまたはサービスにプッシュされます。 サブスクライブされた各サービスは、メッセージの指示どおりに操作を実行し、メッセージ キューへの応答で操作の成功または失敗を報告します。 成功した場合、必要な場合に別のサービスがワークフローを継続できるよう、サービスは同じキューまたは異なるメッセージ キューにメッセージをプッシュ バックできます。 操作が失敗した場合、メッセージ バスはその操作を再試行できます。

このようにして、サービスは、オーケストレーターに依存したり、サービス間で直接通信したりすることなく、サービス間でワークフローの "振り付け" を行います。

ポイントツーポイント通信がないため、このパターンはサービス間の結合を弱めるのに役立ちます。 また、すべてのトランザクションを扱う必要がある場合に、オーケストレーターに起因するパフォーマンスのボトルネックを解消できます。

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

サービスを頻繁に更新または置換し、最終的に一部のサービスを追加または削除することが予想される場合は、コレオグラフィ パターンを使用します。 より少ない労力で、既存のサービスを極力中断せずに、アプリ全体を変更できます。

中央のオーケストレーターでパフォーマンスのボトルネックが発生する場合は、このパターンを検討してください。

このパターンはサーバーレス アーキテクチャの自然なモデルであり、すべてのサービスを短期型またはイベント駆動型にすることができます。 イベントのためにサービスを生成し、サービスのタスクを実行させて、タスクが終了したらサービスを削除することができます。

問題と注意事項

オーケストレーターを非集中化すると、ワークフローの管理中に問題が発生する可能性があります。

サービスがビジネス操作を完了できない場合に、その障害からの復旧が難しい場合があります。 1 つの方法は、イベントを発生させることによってサービスが障害を示すようにする、というものです。 障害を示すイベントをサブスクライブしている別のサービスは、補償トランザクションを適用するなどの必要なアクションを実行して、要求内の成功した操作を元に戻します。 障害が発生したサービスは、障害のイベントを発生させることにも失敗する場合があります。 その場合は、再試行やタイムアウトのメカニズムを使用して、その操作を失敗と認識することを検討してください。 例については、「」のセクションを参照してください。

独立したビジネス操作を並列で処理する場合、ワークフローを実装するのは簡単です。 単一のメッセージ バスを使用できます。 しかし、コレオグラフィを順番に実行する必要がある場合、ワークフローは複雑になる可能性があります。 たとえば、サービス C は、サービス A とサービス B が正常に操作を完了した後でないと操作を開始できません。 1 つのアプローチは、必要な順序でメッセージを取得する複数のメッセージ バスまたはメッセージ キューを設けることです。 詳細については、「」のセクションを参照してください。

サービスの数が急速に増加する場合、コレオグラフィ パターンは困難になります。 独立した移動する要素の多さを考慮すると、サービス間のワークフローは複雑になる傾向があります。 また、分散トレースは困難になります。

オーケストレーターはワークフローの回復性を集中的に管理し、単一障害点になる可能性があります。 これに対して、コレオグラフィの場合は、役割がすべてのサービス間で分散されるため、回復性の堅牢さが低下します。

各サービスは、その操作の回復性だけでなくワークフローにも責任を負います。 この責任はサービスにとって負担になり、実装が難しいことがあります。 各サービスは必要に応じて、要求が正常に終了するように、一時的、非一時的、およびタイムアウトのエラーを再試行する必要があります。 またサービスは、他のサービスがそれに応じた対応ができるよう、操作の成功または失敗をできるだけ伝達する必要があります。

ワークロード設計

設計者は、Azure Well-Architected Framework の柱で説明されている目標と原則に対処するために、ワークロードの設計でどのように振り付けパターンを使用できるかを評価する必要があります。 次に例を示します。

重要な要素 このパターンが柱の目標をサポートする方法
オペレーショナルエクセレンス は、標準化されたプロセスとチームの結束によってワークロードの品質を提供します。 このパターンの分散コンポーネントは自律的で、交換可能なように設計されているため、システム全体の変更を少なくしてワークロードを変更することができます。

- OE:04 ツールとプロセス
パフォーマンスの効率化は、スケーリング、データ、コードを最適化することによって、ワークロードが効率的にニーズを満たすのに役立ちます。 このパターンは、中央集中型オーケストレーショントポロジでパフォーマンスボトルネックが発生した場合の代替方法を提供します。

- PE:02 容量計画
- PE:05 スケーリングとパーティショニング

設計決定と同様に、このパターンで導入される可能性のある他の柱の目標とのトレードオフを考慮してください。

この例では、マイクロサービスと共に関数を実行するイベント ドリブンのクラウド ネイティブ ワークロードを作成することで、コレオグラフィ パターンを示します。 クライアントがパッケージの発送を要求すると、ワークロードによってドローンが割り当てられます。 スケジュールされたドローンでパッケージを受け取る準備ができたら、配送プロセスが開始されます。 転送中、ワークロードは発送済みの状態になるまで配送を処理します。

この例は、オーケストレーター パターンをコレオグラフィ パターンに置き換えたドローン配送の実装のリファクタリングです。

コレオグラフィ パターンを実装するイベント ドリブンのクラウド ネイティブ サンプル ワークロードの図

インジェスト サービスは、クライアント要求を処理し、配信の詳細を含むメッセージに変換します。 ビジネス トランザクションは、これらの新しいメッセージを使用した後に開始されます。

1 つのクライアントのビジネス トランザクションには、パッケージの作成または更新、パッケージを配送するドローンの割り当て、および出荷時のチェックと最終的な認識の向上で構成される配送の適切な処理という 3 つの異なるビジネス オペレーションが必要です。 これらのマイクロサービスでは、Package、Drone Scheduler、および Delivery の各サービスのビジネス処理を行います。 中央のオーケストレーターの代わりに、サービスはメッセージングを使用して相互通信を行います。 各サービスは、ビジネス ワークフローを分散的に調整するプロトコルを事前に実装する必要があります。

デザイン

ビジネス トランザクションは複数のホップを通じて順番に処理されます。 各ホップは、すべてのビジネス サービス間で 1 つのメッセージ バスを共有しています。

クライアントが HTTP エンドポイントを介して配信要求を送信すると、インジェスト サービスはそれを受信し、そのような要求をメッセージに変換してから、共有メッセージ バスにメッセージを発行します。 サブスクライブしているビジネス サービスは、バスに追加された新しいメッセージを使用します。 メッセージを受信すると、ビジネス サービスが操作を完了して成功または失敗を返す場合と、要求がタイムアウトになる場合があります。成功した場合、サービスは Ok ステータス コードでバスに応答し、新しい操作メッセージを発生させて、メッセージ バスに送信します。 エラーまたはタイムアウトが発生した場合、サービスは理由コードをメッセージ バスに送信してエラーを報告します。 さらに、メッセージは後で処理するために配信不能になります。 合理的かつ適切な時間内に受信または処理できなかったメッセージは、同様に DLQ に移動されます。

この設計では、複数のメッセージ バスを使用してビジネス トランザクション全体を処理します。 Microsoft Azure Service BusMicrosoft Azure Event Grid は、この設計用のメッセージング サービス プラットフォームを提供するように構成されています。 ワークロードは、インジェストのために Azure Functions をホストする Azure Container Apps と、ビジネス ロジックを実行するイベント ドリブン処理を処理するアプリにデプロイされます。

この設計により、コレオグラフィがシーケンスで確実に行われます。 1 つの Azure Service Bus 名前空間には、2 つのサブスクリプションとセッション対応キューを含むトピックが含まれています。 インジェスト サービスは、トピックにメッセージを発行します。 Package サービスと Drone Scheduler サービスはトピックをサブスクライブし、成功をキューに伝えるメッセージを発行します。 配信識別子に関連付けられた GUID を持つ共通セッション識別子を含めると、関連するメッセージの無制限シーケンスの順序付けされた処理が可能になります。 Delivery サービスは、トランザクションごとに 2 つの関連メッセージを待機します。 最初のメッセージは、パッケージを出荷する準備ができていることを示し、2 番目のメッセージはドローンがスケジュールされていることを示します。

この設計では、Azure Service Bus を使用して、配信プロセス全体で失われたり重複したりできない価値の高いメッセージを処理します。 パッケージが出荷されると、状態の変更も Azure Event Grid に発行されます。 この設計では、イベントの送信元は、状態の変更がどのように処理されるかについて何も予測していません。 この設計の一部として含まれていないダウンストリーム組織サービスは、このイベントの種類をリッスンし、特定のビジネス目的ロジック (つまり、出荷済み注文の状態をユーザーにメールで送信) を実行する場合があります。

これを AKS パブリッシュ/サブスクライブ パターンの定型アプリケーションのような別のコンピューティング サービスにデプロイする予定があるなら、同じポッド内の 2 つのコンテナで実装できます。 1 つのコンテナーは優先するメッセージ バスとやりとりするアンバサダーを実行し、もう 1 つのコンテナーはビジネス ロジックを実行します。 同じポッドに 2 つのコンテナーを置くアプローチにより、パフォーマンスとスケーラビリティが向上します。 アンバサダーとビジネス サービスは同じネットワークを共有するので、短い待機時間と高いスループットが実現します。

複数の作業につながる可能性のあるカスケード型再試行操作を回避するために、ビジネス サービスは、許容できないメッセージに直ちにフラグを設定する必要があります。 このようなメッセージは、よく知られた理由コードや定義されたアプリケーション コードを使ってエンリッチすることが可能で、配信不能キュー (DLQ) に移動させることができます。 ダウンストリームのサービスから Saga を実装する場合、整合性の問題を管理することを検討してください。 たとえば、別のサービスでは、修復目的で配信不能メッセージを処理するには、補償、再試行、またはピボット トランザクションを実行する必要があります。

再試行操作によってリソースが重複しないことを保証するために、ビジネス サービスの結果は常に同じです。 たとえば、Package サービスは upsert 操作を使用してデータをデータ ストアに追加します。

コレオグラフィの設計では、これらのパターンを検討してください。