編集

次の方法で共有


イベント ドリブン アーキテクチャのスタイル

Azure Stream Analytics
Azure Functions
Azure Service Bus

イベント ドリブン アーキテクチャは、イベントのストリームを生成する イベント プロデューサー これらのイベントをリッスンする イベント コンシューマー 、およびプロデューサーからコンシューマーにイベントを転送する イベント チャネル で構成されます。

イベント ドリブン アーキテクチャのスタイルの図

イベントはほぼリアルタイムで配信されるため、イベントが発生するとコンシューマーはすぐに応答できます。 プロデューサーはコンシューマーから分離されており、プロデューサーはどのコンシューマーがリッスンしているのかを認識しません。 コンシューマーも互いに分離されており、すべてのコンシューマーがすべてのイベントを見ることができます。 これは競合コンシューマー パターンとは異なり、コンシューマーがキューからメッセージを取得し、メッセージは一度だけ処理されます (エラーは想定されません)。 IoT などの一部のシステムでは、イベントを大量に取り込む必要があります。

イベント ドリブン アーキテクチャでは、パブリッシュ/サブスクライブ ("pub/sub" とも呼ばれます)モデルやイベント ストリーム モデルを使用できます。

  • パブリッシュ/サブスクライブ:メッセージング インフラストラクチャではサブスクリプションを追跡します。 イベントが発行されると、各サブスクライバーにイベントが送信されます。 イベント受信後は、イベントを再生することはできません。また、そのイベントは新しいサブスクライバーに表示されません。

  • イベント ストリーミング:イベントがログに書き込まれます。 イベントは (パーティション内で) 厳密に順序付けされ、持続します。 クライアントはストリームにサブスクライブしませんが、その代わり、ストリームのどの部分からでも読み取ることができます。 ストリーム内でクライアントの位置を進めるのは、クライアントの役割です。 つまりクライアントはいつでも参加でき、イベントを再生できます。

コンシューマー側には、いくつかの一般的なバリエーションがあります。

  • 簡単なイベント処理。 イベントがコンシューマーのアクションを即時トリガーします。 たとえば、お客様は Service Bus トリガーを備えた Azure Functions を使用でき、それにより、Service Bus トピックにメッセージが発行されるたびに関数が実行されます。

  • 基本的なイベントの相関関係。 コンシューマーは、少数の個別のビジネス イベントを処理する必要があります。通常は、何らかの識別子で関連付けられ、後でイベントを処理するときに使用するために以前のイベントの情報が保持されます。 このパターンは、NServiceBusMassTransit などのライブラリでサポートされています。

  • 複合イベント処理。 コンシューマーは一連のイベントを処理し、Azure Stream Analytics などのテクノロジを使用してイベント データのパターンを検索します。 たとえば、組み込みデバイスからの測定値を時間枠で集計し、移動平均が特定のしきい値を超えた場合に通知を生成することができます。

  • イベント ストリーム処理. Azure IoT Hub や Apache Kafka などのデータ ストリーミング プラットフォームを、イベントを取り込んでストリーム プロセッサにフィードするパイプラインとして使用します。 ストリーム プロセッサは、ストリームの処理や変換を行います。 アプリケーションの異なるサブシステムに対して、複数のストリーム プロセッサが存在する場合があります。 この手法は IoT ワークロードに適しています。

イベントのソースはシステムの外部にある場合があります。たとえば、IoT ソリューションの物理デバイスなどです。 その場合、システムはデータ ソースで必要なボリュームとスループットでデータを取り込むことができる必要があります。

上記の図では、コンシューマーが種類ごとに 1 つのボックスで表示されています。 実際には、1 つのコンシューマーに複数のインスタンスがあるのが一般的ですが、それはコンシューマーがシステムの単一障害点にならないようにするためです。 イベントのボリュームと頻度を制御するのに、複数のインスタンスが必要になることもあります。 また、1 つのコンシューマーが複数のスレッドのイベントを処理することもあります。 イベントを順番に処理しなければならない、または正確に 1 回のセマンティクスが必要な場合には、このために課題が発生することがあります。 「Minimize Coordination (調整を最小限に抑える)」をご覧ください。

多くのイベント ドリブン アーキテクチャには、次の 2 つの主要なトポロジがあります。

  • ブローカー トポロジ。 コンポーネントはイベントとしてシステム全体にブロードキャストし、他のコンポーネントはイベントに対して動作するか、イベントを無視します。 このトポロジは、イベント処理フローが比較的単純な場合に便利です。 中央の調整やオーケストレーションがないため、このトポロジは非常に動的な場合があります。 このトポロジは高度分離されており、スケーラビリティ、応答性、およびコンポーネントの耐障害性を提供するのに役立ちます。 コンポーネントは、マルチステップ ビジネス トランザクションの状態を所有または認識することはなく、動作は非同期的に実行されます。 その後、分散されたトランザクションは、再起動または再生するためのネイティブな手段がないため、危険です。 このトポロジはデータ不整合の原因になる可能性があるため、エラー処理と手動の介入戦略を慎重に検討する必要があります。

  • メディエーター トポロジ。 このトポロジは、ブローカー トポロジの欠点の一部に対処します。 イベントのフローを管理したり制御するイベント メディエーターがあります。 イベント メディエーターは状態を維持し、エラー処理と再起動の機能を管理します。 コンポーネントはブローカー トポロジーとは異なり、指定されたチャネル (通常はメッセージ キュー) にのみ、出現箇所をコマンドとしてブロードキャストします。 これらのコマンドは、コンシューマーによって無視されることは想定されていません。 このトポロジでは、制御が強化され、分散エラー処理が向上し、データの整合性が向上する可能性があります。 このトポロジでは、コンポーネント間の結合が増え、イベント メディエーターが支障または信頼性の問題になる可能性があります。

このアーキテクチャを使用する状況

  • 複数のサブシステムで同じイベントを処理する必要がある。
  • 最小のタイム ラグのリアルタイム処理。
  • パターン マッチングや時間枠での集計などの複合イベント処理。
  • IoT などの高ボリューム、高ベロシティのデータ。

メリット

  • プロデューサーとコンシューマーが分離。
  • ポイント ツー ポイントの統合はなし。 システムに新しいコンシューマーを追加するのが簡単。
  • コンシューマーは、イベントが到着するとすぐに応答可能。
  • 拡張性、柔軟性、分散性が高い。
  • サブシステムにイベント ストリームの独立したビューがある。

課題

  • 保証された配信。

    一部のシステムでは (特に IoT シナリオで)、イベントが配信されたことを保証することが重要です。

  • イベントを順番に、または正確に 1 回処理。

    各コンシューマー タイプは通常、回復性とスケーラビリティのために複数のインスタンスで実行されます。 (コンシューマー タイプ内で) 順番にイベントを処理する必要がある場合や、べき等メッセージ処理ロジックが実装されていない場合、これにより課題が生じる可能性があります。

  • サービス間のメッセージの調整。

    多くの場合、ビジネス プロセスには、ワークロード全体で一貫した結果を実現するために、複数のサービスの発行とメッセージのサブスクライブが含まれています。 コレオグラフィ パターンSaga オーケストレーションなどのワークフロー パターンは、さまざまなサービスにわたってメッセージ フローを確実に管理するために使用できます。

  • エラー処理。

    イベント駆動アーキテクチャでは、主に非同期通信が使用されます。 非同期通信の課題は、エラー処理です。 この問題に対処する 1 つの方法は、別のエラー ハンドラー プロセッサを使用することです。 そのため、イベント コンシューマーは、エラーが発生すると、エラー ハンドラー プロセッサにエラー イベントを直ちに非同期的に送信し、次に進みます。 エラー ハンドラー プロセッサはエラーの修正を試み、イベントを元のインジェスト チャネルに送り返します。 ただし、エラー ハンドラー プロセッサが失敗した場合は、エラー イベントを管理者に送信してさらに検査することができます。 エラー ハンドラー プロセッサを使用する場合、エラー イベントは再送信時に順番に処理されません。

  • データ損失。

    非同期通信のもう 1 つの課題は、データ損失です。 いずれかのコンポーネントがクラッシュした後、イベントが正常に処理され、次のコンポーネントに渡された場合、イベントは破棄され、最終的な宛先になることはありません。 データ損失の可能性を最小限に抑えるには、転送中のイベントを保持し、次のコンポーネントがイベントの受信を確認した場合にのみ、イベントを削除またはデキューします。 これらの機能は、通常、 client 受信確認モード および last 参加者サポートと呼ばれます

  • 従来の要求/応答パターンの実装。

    場合によっては、イベント プロデューサーは、注文を続行する前に顧客の適格性を取得するなど、イベント コンシューマーからの即時の応答を必要とします。 イベント ドリブン アーキテクチャでは、 request-response メッセージングを使用して同期通信を実現できます

    通常、このパターンは、要求キューと応答キューという複数のキューを使用して実装されます。 イベント プロデューサーは、要求キューに非同期要求を送信し、そのタスクに対する他の操作を一時停止し、応答キュー内の応答を待機します。これを同期プロセスに効果的に変換します。 その後、イベント コンシューマーは要求を処理し、応答キューを介して返信を送信します。 この方法では通常、追跡にセッション ID が使用されるため、イベント プロデューサーは、応答キュー内のどのメッセージが特定の要求に関連するかを認識します。 元の要求では、応答キューの名前 (一時的な可能性がある) を reply-to ヘッダー またはその他の相互に合意されたカスタム属性で指定することもできます。

  • 適切な数のイベントを維持する。

    過剰な数のきめ細かいイベントを生成すると、システムが飽和して過剰になり、イベントの全体的なフローを効果的に分析することが困難になる可能性があります。 この問題は、変更をロールバックする必要があるときに悪化します。 逆に、イベントを過度に統合すると問題が発生し、イベント コンシューマーからの不要な処理と応答が発生する可能性もあります。

    適切なバランスを実現するには、イベントの結果と、コンシューマーが応答を決定するためにイベント ペイロードを検査する必要があるかどうかを検討します。 たとえば、コンプライアンス チェック コンポーネントがある場合は、 準拠 非準拠 の 2 種類のイベントのみを発行するだけで十分な場合があります。 この方法では、各イベントを関連するコンシューマーのみが処理できるため、不要な処理を防ぐことができます。

その他の注意点

  • イベントに含めるデータの量は、パフォーマンスとコストの両方に影響するので、慎重に検討する必要があります。 処理に必要なすべての関連情報をイベント自体に格納すると、処理コードが簡素化され、追加の検索回数を減らすことができます。 最小限の情報 (少数の識別子のみ、など) をイベントに格納すると、転送時間とコストは削減されますが、必要な追加情報を検索するには処理コードが必要になります。 これの詳細については、こちらのブログ記事を参照してください。
  • 要求は要求処理コンポーネントにのみ表示されますが、多くの場合、それらのコンポーネントがそれらのコンポーネントを使用しない、または使用する予定がない場合でも、イベントはワークロード内の複数のコンポーネントに対して表示されます。 「侵害を想定」 して運用する場合は、意図しない情報漏えいを防ぐために、イベントに含める情報に注意してください。
  • 多くのアプリケーションでは、プライマリ アーキテクチャとしてイベント ドリブン アーキテクチャが使用されます。ただし、このアプローチを他のアーキテクチャ スタイルと組み合わせて使用すると、ハイブリッド アーキテクチャを作成できます。 一般的な組み合わせには、 microservicesパイプとフィルターが含まれます。 イベントドリブン アーキテクチャを統合すると、ボトルネックを排除し、要求量が多い場合にバック圧力を提供することで、システムのパフォーマンスが向上します。
  • 特定のドメイン は、多くの場合、複数のイベント プロデューサー、コンシューマー、またはイベント チャネルにまたがっています。 特定のドメインに対する変更は、多くのコンポーネントに影響する可能性があります。