イベント ドリブン アーキテクチャのスタイル
イベント ドリブン アーキテクチャは、イベントのストリームを生成する イベント プロデューサー これらのイベントをリッスンする イベント コンシューマー 、およびプロデューサーからコンシューマーにイベントを転送する イベント チャネル で構成されます。
イベントはほぼリアルタイムで配信されるため、イベントが発生するとコンシューマーはすぐに応答できます。 プロデューサーはコンシューマーから切り離されます。プロデューサーは、どのコンシューマーがリッスンしているのかを認識しません。 コンシューマーも互いに分離されており、すべてのコンシューマーがすべてのイベントを見ることができます。 このプロセスは、コンシューマーがキューからメッセージをプルし、メッセージが 1 回だけ処理される 競合コンシューマー パターン とは異なります。エラーがないことを前提としています。 Azure モノのインターネット (IoT) などの一部のシステムでは、イベントを大量に取り込む必要があります。
イベント ドリブン アーキテクチャでは、 パブリッシュ/サブスクライブ モデル またはイベント ストリーム モデルを使用できます。
Pub/sub: パブリッシュ/サブスクライブ メッセージング インフラストラクチャは、サブスクリプションを追跡します。 イベントが発行されると、各サブスクライバーにイベントが送信されます。 受信後にイベントを再生することはできません。また、新しいサブスクライバーにはイベントが表示されません。
イベント ストリーミング: イベントはログに書き込まれます。 イベントはパーティション内で厳密に順序付けされ、永続的です。 クライアントはストリームをサブスクライブしません。 代わりに、クライアントはストリームの任意の部分から読み取ることができます。 クライアントは、ストリーム内での位置を進める責任を負います。 つまり、クライアントはいつでも参加でき、イベントを再生できます。
コンシューマー側には、いくつかの一般的なバリエーションがあります。
単純なイベント処理: イベントによって、コンシューマー内のアクションが直ちにトリガーされます。 たとえば、メッセージが Service Bus トピックに発行されるたびに関数が実行されるように、Azure Service Bus トリガーで Azure Functions を使用できます。
基本的なイベントの相関関係: コンシューマーは、いくつかの個別のビジネス イベントを処理し、それらをいくつかの識別子によって関連付け、後でイベントを処理するときに使用するために以前のイベントからの情報を保持します。 NServiceBus や MassTransit などのライブラリでは、このパターンがサポートされています。
複雑なイベント処理: コンシューマーは、Azure Stream Analytics などのテクノロジを使用して一連のイベントを分析し、イベント データ内のパターンを識別します。 たとえば、埋め込みデバイスからの読み取り値を時間枠で集計し、移動平均が特定のしきい値を超えた場合に通知を生成できます。
イベント ストリーム処理: イベントを取り込んでストリーム プロセッサにフィードするパイプラインとして、Azure IoT Hub や Apache Kafka などのデータ ストリーミング プラットフォームを使用します。 ストリーム プロセッサは、ストリームの処理や変換を行います。 アプリケーションのサブシステムごとに複数のストリーム プロセッサが存在する可能性があります。 この手法は IoT ワークロードに適しています。
イベントのソースは、IoT ソリューションの物理デバイスなど、システムの外部にある可能性があります。 その場合、システムは、データ ソースに必要なボリュームとスループットでデータを取り込める必要があります。
イベント ペイロードを構造化するには、主に 2 つの方法があります。 イベント コンシューマーを制御できる場合は、各コンシューマーのペイロード構造を決定できます。 この戦略により、1 つのワークロード内で必要に応じてアプローチを混在させることができます。
ペイロードに必要なすべての属性を含めます。 この方法は、コンシューマーが外部データ ソースに対してクエリを実行することなく、使用可能なすべての情報を取得する場合に使用します。 ただし、特に更新後に、複数 のレコード システムが原因でデータの整合性の問題が発生する可能性があります。 コントラクトの管理とバージョン管理も複雑になる可能性があります。
ペイロードにキーのみを含めます。 この方法では、コンシューマーは、データ ソースから残りのデータを個別にフェッチするために必要な属性 (主キーなど) を取得します。 このメソッドでは、単一のレコード システムがあるため、データの整合性が向上します。 ただし、コンシューマーはデータ ソースに頻繁にクエリを実行する必要があるため、最初のアプローチよりもパフォーマンスが低下する可能性があります。 イベントが小さくなり、コントラクトが単純になるため、結合、帯域幅、コントラクト管理、またはバージョン管理に関する懸念が少なくなります。
上の図では、各種類のコンシューマーが 1 つのボックスとして表示されています。 コンシューマーがシステムの単一障害点にならないようにするには、コンシューマーのインスタンスが複数あるのが一般的です。 イベントのボリュームと頻度を処理するために、複数のインスタンスが必要になる場合もあります。 1 つのコンシューマーが複数のスレッドでイベントを処理できます。 このセットアップでは、イベントを順番に処理する必要がある場合、または 1 回だけセマンティクスを必要とする場合に、チャレンジを作成できます。 詳細については、「調整の 最小化」を参照してください。
多くのイベント ドリブン アーキテクチャには、次の 2 つの主要なトポロジがあります。
ブローカー トポロジ: コンポーネントは、発生をイベントとしてシステム全体にブロードキャストします。 他のコンポーネントは、イベントに対して動作するか、イベントを無視します。 このトポロジは、イベント処理フローが比較的単純な場合に便利です。 中央の調整やオーケストレーションがないため、このトポロジは動的にすることができます。 このトポロジは高度分離されており、スケーラビリティ、応答性、およびコンポーネントの耐障害性を提供するのに役立ちます。 コンポーネントは、マルチステップ ビジネス トランザクションの状態を所有または認識することはなく、動作は非同期的に実行されます。 その後、分散トランザクションは、再起動または再生するネイティブな方法がないため、危険です。 このトポロジはデータの不整合の原因になる可能性があるため、エラー処理と手動介入戦略を慎重に検討する必要があります。
メディエーター トポロジ: このトポロジは、ブローカー トポロジの欠点の一部に対処します。 イベントのフローを管理および制御するイベント メディエーターがあります。 イベント メディエーターは状態を維持し、エラー処理と再起動の機能を管理します。 ブローカー トポロジとは対照的に、このトポロジでは、コンポーネントは、指定されたチャネルにのみ、コマンドとして発生をブロードキャストします。 通常、これらのチャネルはメッセージ キューです。 コンシューマーは、これらのコマンドを処理する必要があります。 このトポロジにより、制御が強化され、分散エラー処理が向上し、データの整合性が向上する可能性があります。 このトポロジでは、コンポーネント間の結合が増え、イベント メディエーターがボトルネックまたは信頼性の問題になる可能性があります。
このアーキテクチャを使用する状況
このアーキテクチャは、次の場合に使用する必要があります。
- 複数のサブシステムで同じイベントを処理する必要がある。
- タイム ラグを最小限に抑えたリアルタイム処理が必要です。
- パターン マッチングや時間経過に伴う集計などの複雑なイベント処理が必要です。
- IoT などと同様に、大量のデータと高速のデータが必要です。
メリット
このアーキテクチャの利点は次のとおりです。
- プロデューサーとコンシューマーが分離。
- ポイント ツー ポイントの統合はなし。 システムに新しいコンシューマーを追加するのが簡単。
- コンシューマーは、発生したイベントにすぐに応答できます。
- 拡張性、柔軟性、分散性が高い。
- サブシステムにイベント ストリームの独立したビューがある。
課題
保証された配信。
一部のシステムでは (特に IoT シナリオで)、イベントが配信されたことを保証することが重要です。
イベントを順番に、または正確に 1 回処理。
回復性とスケーラビリティのために、各コンシューマーの種類は通常、複数のインスタンスで実行されます。 このプロセスは、コンシューマーの種類内でイベントを順番に処理する必要がある場合、または べき等メッセージ処理 ロジックが実装されていない場合にチャレンジを作成できます。
サービス間のメッセージ調整。
ビジネス プロセスには、多くの場合、ワークロード全体で一貫した結果を実現するために、メッセージを発行してサブスクライブする複数のサービスがあります。 振付パターンや Saga オーケストレーションなどのワークフロー パターンを使用して、さまざまなサービス間のメッセージ フローを確実に管理できます。
エラー処理。
イベント ドリブン アーキテクチャでは、主に非同期通信が使用されます。 非同期通信の課題は、エラー処理です。 この問題に対処する 1 つの方法は、別のエラー ハンドラー プロセッサを使用することです。 イベント コンシューマーは、エラーが発生すると、エラー ハンドラー プロセッサにエラー イベントを直ちに非同期的に送信して、次に進みます。 エラー ハンドラー プロセッサはエラーの修正を試み、イベントを元のインジェスト チャネルに送り返します。 ただし、エラー ハンドラー プロセッサが失敗した場合は、エラーイベントを管理者に送信してさらに検査することができます。 エラー ハンドラー プロセッサを使用する場合、エラー イベントは再送信時に順番に処理されません。
データ損失。
非同期通信のもう 1 つの課題は、データ損失です。 いずれかのコンポーネントがクラッシュした後、イベントが正常に処理され、次のコンポーネントに渡された場合、イベントは破棄され、最終的な宛先になることはありません。 データ損失の可能性を最小限に抑えるには、転送中のイベントを保持し、次のコンポーネントがイベントの受信を確認した場合にのみ、イベントを削除またはデキューします。 これらの機能は、 クライアント受信確認モード および 最後の参加者サポートと呼ばれます。
従来の要求/応答パターンの実装。
イベント プロデューサーは、注文を続行する前に顧客の適格性を取得するなど、イベント コンシューマーからの即時応答を必要とする場合があります。 イベント ドリブン アーキテクチャでは、 要求/応答メッセージングを使用して同期通信を実現できます。
通常、このパターンは、要求キューと応答キューの 2 つのキューで実装されます。 イベント プロデューサーは、要求キューに非同期要求を送信し、そのタスクに対する他の操作を一時停止し、応答キュー内の応答を待機します。 この方法では、このパターンを効果的に同期プロセスに変換します。 その後、イベント コンシューマーは要求を処理し、応答キューを介して返信を送信します。 この方法では通常、追跡にセッション ID が使用されるため、イベント プロデューサーは、応答キュー内のどのメッセージが特定の要求に関連しているかを認識します。 元の要求では、 応答先ヘッダー または相互に合意された別のカスタム属性で、応答キューの名前 (一時的な可能性がある) を指定することもできます。
適切な数のイベントのメンテナンス。
過剰な数のきめ細かいイベントを生成すると、システムが飽和して過剰になり、イベントの全体的なフローを効果的に分析することが困難になる可能性があります。 この問題は、変更をロールバックする必要があるときに悪化します。 逆に、イベントを過度に統合すると問題が発生し、イベント コンシューマーからの不要な処理と応答が発生する可能性もあります。
適切なバランスを実現するには、イベントの結果と、コンシューマーが応答を決定するためにイベント ペイロードを検査する必要があるかどうかを検討します。 たとえば、コンプライアンス チェック コンポーネントがある場合は、 準拠 イベントと 非準拠イベントの 2 種類のイベントのみを発行するだけで十分な場合があります。 この方法は、関連するコンシューマーのみが各イベントを処理し、不要な処理を防ぐのに役立ちます。
その他の考慮事項
イベントに含めるデータの量は、パフォーマンスとコストの両方に影響するので、慎重に検討する必要があります。 処理に必要なすべての関連情報をイベントに直接配置することで、処理コードを簡略化し、余分な参照を排除できます。 少数の識別子など、最小限の情報のみをイベントに追加すると、トランスポート時間とコストが削減されます。 ただし、この方法では、必要な追加情報を取得する処理コードが必要です。 詳細については、「 食事にイベントを配置する」を参照してください。
要求は、要求処理コンポーネントにのみ表示されます。 ただし、多くの場合、イベントはワークロード内の複数のコンポーネントに対して表示されます。ただし、それらのコンポーネントがそれらのコンポーネントを使用しない、または使用しない場合でも、イベントは表示されます。 "侵害を想定する" 考え方で運用するには、意図しない情報の漏洩を防ぐために、イベントに含める情報に注意してください。
多くのアプリケーションでは、プライマリ アーキテクチャとしてイベント ドリブン アーキテクチャが使用されています。 このアプローチを他のアーキテクチャ スタイルと組み合わせて、ハイブリッド アーキテクチャを作成できます。 一般的な組み合わせには、 マイクロサービス と パイプとフィルターが含まれます。 イベントドリブン アーキテクチャを統合して、ボトルネックを排除し、高い要求量の間に 背圧 を提供することで、システムのパフォーマンスを向上させます。
特定のドメイン は、多くの場合、複数のイベント プロデューサー、コンシューマー、またはイベント チャネルにまたがっています。 特定のドメインに対する変更は、多くのコンポーネントに影響する可能性があります。
関連リソース
- コレオグラフィとオーケストレーションの選択の考慮事項に関するコミュニティ ディスカッション ビデオ。