イベント駆動型アーキテクチャ(EDA)は、イベントの生成と検出に関するソフトウェアアーキテクチャパラダイムです。イベント駆動型アーキテクチャは進化的な性質を持ち、高い耐障害性、パフォーマンス、スケーラビリティを提供します。しかし、複雑で本質的にテストが困難です。EDAは複雑で動的なワークロードに適しています。[ 1 ]
イベントは「状態の重大な変化」と定義できます。[ 2 ]例えば、消費者が車を購入すると、車の状態は「販売中」から「販売済み」に変わります。自動車販売店のシステムアーキテクチャでは、この状態変化を、アーキテクチャ内の他のアプリケーションに通知できるイベントとして扱う場合があります。形式的な観点から言えば、生成、公開、伝播、検出、または消費されるのは、イベント通知と呼ばれる(通常は非同期の)メッセージであり、メッセージの発信をトリガーした状態変化であるイベントそのものではありません。イベントは伝わるのではなく、発生するだけです。ただし、イベントという用語は通知メッセージ自体を表す換喩としてよく使用されるため、混乱を招く可能性があります。これは、イベント駆動型アーキテクチャがメッセージ駆動型アーキテクチャの上に設計されることが多く、そのような通信パターンでは、各通信の処理方法を区別するために、入力の1つがテキストのみであるメッセージである必要があるためです。
このアーキテクチャパターンは、疎結合されたソフトウェアコンポーネントとサービス間でイベントを伝送するアプリケーションやシステムの設計と実装に適用できます。イベント駆動型システムは通常、イベントエミッター(またはエージェント)、イベントコンシューマー(またはシンク)、およびイベントチャネルで構成されます。エミッターは、イベントを検出、収集、転送する責任を負います。イベントエミッターは、イベントのコンシューマーを知りません。コンシューマーが存在するかどうかも知らず、存在する場合でも、イベントがどのように使用されるか、またはさらに処理されるかを知りません。シンクは、イベントが提示されるとすぐに反応を適用する責任を負います。反応は、シンク自身によって完全に提供される場合もあれば、そうでない場合もあります。たとえば、シンクはイベントをフィルタリング、変換して別のコンポーネントに転送する責任のみを負う場合もあれば、そのようなイベントに対して自己完結型の反応を提供する場合もあります。イベントチャネルは、イベントがイベントエミッターからイベントコンシューマーに伝送される経路です。イベントの正しい配信に関する知識は、イベントチャネル内にのみ存在します。イベントチャネルの物理的な実装は、メッセージ指向ミドルウェアやポイントツーポイント通信などの従来型のコンポーネントに基づいている場合があり、より適切なトランザクション実行フレームワークが必要になる可能性があります。
イベント駆動型アーキテクチャに基づいてシステムを構築すると、分散コンピューティングモデルにおける水平スケーラビリティが簡素化され、障害に対する耐性が向上します。これは、アプリケーションの状態を複数の並列スナップショットにコピーして高可用性を実現できるためです。[ 3 ]新しいイベントはどこからでも開始できますが、さらに重要なのは、到着するたびにデータ ストアのネットワーク全体に伝播し、それぞれを更新できることです。ノードの追加も簡単になります。アプリケーションの状態のコピーを取得し、イベント ストリームをフィードして実行するだけです。[ 4 ]
イベント駆動型アーキテクチャは、サービス指向アーキテクチャ(SOA)を補完することができます。なぜなら、サービスは受信イベントで発生するトリガーによってアクティブ化されるからです。[ 5 ] [ 6 ]このパラダイムは、シンクが自己完結型のエグゼクティブ を提供しない場合に特に役立ちます。
SOA 2.0は、これまで知られていなかった因果関係を活用して新たなイベントパターンを形成することで、SOAおよびEDAアーキテクチャが提供する可能性をより豊かで堅牢なレベルへと進化させます。この新たなビジネスインテリジェンスパターンは、自律的な人間または自動化された処理をさらに促進し、これまで実現できなかった付加価値情報を認識されたパターンに注入することで、企業に飛躍的な価値をもたらします。
イベント駆動型アーキテクチャには、主に 2 つのトポロジがあります。「ブローカー トポロジ」では、コンポーネントはオーケストレーターなしでシステム全体にイベントをブロードキャストします。このトポロジは、より高いパフォーマンスとスケーラビリティを提供します。「メディエーター トポロジ」では、イベントのワークフローを制御する中央オーケストレーターがあります。このトポロジは、より優れた制御とエラー処理機能を提供します。ハイブリッド モデルを使用して、これら 2 つのトポロジを組み合わせることもできます。[ 1 ]
EDAにはさまざまな種類のイベントがあり、その分類に関する意見は異なる場合があります。Yan Cuiによると、イベントには2つの主要なカテゴリがあります。[ 7 ]
ドメインイベントは、特定のビジネスドメイン内で発生する重要な事象を示します。これらのイベントは境界付けられたコンテキストに限定され、ビジネスロジックを維持するために不可欠です。通常、ドメインイベントはペイロードが軽く、処理に必要な情報のみが含まれています。これは、イベントリスナーが一般的に同じサービス内にあり、その要件がより明確に理解されているためです。[ 7 ]
一方、統合イベントは、異なる境界コンテキスト間で変更を伝達する役割を果たします。これらは、システム全体でデータの一貫性を確保するために不可欠です。統合イベントは、潜在的なリスナーのニーズが大きく異なる可能性があるため、追加の属性を持つより複雑なペイロードを持つ傾向があります。これは多くの場合、より徹底したコミュニケーションのアプローチにつながり、すべての関連情報が効果的に共有されるようにするために過剰なコミュニケーションが生じることになります。[ 7 ]
イベントは、イベントヘッダーとイベントボディ(イベントペイロードとも呼ばれる)の2つの部分で構成されます。イベントヘッダーには、イベント名、イベントのタイムスタンプ、イベントの種類などの情報が含まれる場合があります。イベントペイロードには、検出された状態変化の詳細が含まれます。イベントボディは、イベントの発生自体に対応して適用されるパターンやロジックと混同しないように注意が必要です。
イベント駆動型アーキテクチャでは、イベントペイロードを構造化するための主な方法が 2 つあります。[ 1 ]
これらの方法は、二者択一ではなく、スペクトルの両極端を表しています。アーキテクトは、イベントコンシューマーの特定のニーズを満たすために、イベントペイロードのサイズを慎重に調整する必要があります。[ 1 ]
イベント駆動型アーキテクチャでは、イベントの進化は、サービス間で一貫性のないイベントスキーマを管理したり、段階的なシステム更新中に互換性を確保したりするなど、課題をもたらします。イベント駆動型アーキテクチャ (EDA) におけるイベント進化戦略は、システムが中断なくイベントの変更を処理できるようにします。これらの戦略には、後方互換性と前方互換性を維持するために、セマンティック バージョニングやスキーマ進化などのイベントのバージョン管理が含まれます。アダプタは、古い形式と新しい形式の間でイベントを変換し、コンポーネント間で一貫した処理を保証します。これらの技術により、複雑な分散環境において、互換性と信頼性を維持しながらシステムを進化させることができます。[ 9 ]
イベント駆動型アーキテクチャは、イベント(重要な時間的状態または事実)の感知から始まり、イベント構造の形でその技術的表現の作成に進み、そのイベントに対する空でない一連の反応で終わる、4つの論理レイヤーに基づいて構築される可能性がある。[ 10 ]
最初の論理層はイベントプロデューサーであり、イベントプロデューサーは事実を感知し、その事実をイベントメッセージとして表現します。例えば、イベントプロデューサーとしては、電子メールクライアント、Eコマースシステム、監視エージェント、あるいは何らかの物理センサーなどが挙げられます。
このような多様なデータソースから収集したデータを、評価用の単一の標準化されたデータ形式に変換することは、この最初の論理レイヤーの設計と実装において重要なタスクです。[ 10 ]しかし、イベントは強力な宣言的フレームであることを考慮すると、あらゆる情報操作を容易に適用できるため、高度な標準化の必要性がなくなります。
これは第 2 の論理レイヤーです。イベント チャネルは、イベント ジェネレータから収集された情報をイベント エンジン[ 10 ]またはシンクに伝播するメカニズムです。これは TCP/IP 接続、またはあらゆる種類の入力ファイル (フラット、XML形式、電子メールなど) である可能性があります。複数のイベント チャネルを同時に開くことができます。通常、イベント処理エンジンはそれらをほぼリアルタイムで処理する必要があるため、イベント チャネルは非同期で読み取られます。イベントはキューに格納され、後でイベント処理エンジンによって処理されるのを待ちます。
イベント処理エンジンは、イベントを識別し、適切な反応を選択して実行する論理レイヤーです。また、さまざまなアサーションをトリガーすることもできます。たとえば、イベント処理エンジンに入力されたイベントが在庫が少ない製品IDである場合、「製品IDを注文する」や「担当者に通知する」などの反応がトリガーされる可能性があります。[ 10 ]
これは、イベントの結果が表示される論理レイヤーです。これはさまざまな方法や形式で行うことができます。たとえば、電子メールが誰かに送信され、アプリケーションが画面に何らかの警告を表示する場合があります。[ 10 ]シンク(イベント処理エンジン)によって提供される自動化のレベルによっては、下流のアクティビティは必要ない場合があります。
イベント処理には、単純、ストリーム、複雑の3つの一般的なスタイルがあります。これら3つのスタイルは、成熟したイベント駆動型アーキテクチャでよく一緒に使用されます。[ 10 ]
単純イベント処理は、特定の測定可能な状態変化に直接関連するイベントを扱います。単純イベント処理では、注目すべきイベントが発生し、下流のアクションが開始されます。単純イベント処理は、リアルタイムの作業フローを推進するためによく使用され、遅延時間とコストを削減します。[ 10 ]
例えば、タイヤの空気圧や周囲温度の変化をセンサーが検知することで、簡単なイベントを発生させることができます。車のタイヤの空気圧が異常になると、センサーから簡単なイベントが発生し、黄色いライトが点灯してドライバーにタイヤの状態を知らせます。
イベントストリーム処理(ESP)では、通常のイベントと注目すべきイベントの両方が発生します。通常のイベント(注文、RFID送信)は注目に値するかどうかスクリーニングされ、情報購読者にストリーミングされます。イベントストリーム処理は、企業内外におけるリアルタイムの情報フローを促進するために一般的に使用され、タイムリーな意思決定を可能にします。[ 10 ]
複雑イベント処理(CEP)は、単純で通常のイベントのパターンを考慮して、複雑なイベントが発生したことを推測することを可能にします。複雑イベント処理は、イベントの合流を評価し、その後アクションを実行します。イベント(注目すべきイベントまたは通常のイベント)は、イベントの種類をまたぎ、長期間にわたって発生する可能性があります。イベントの相関関係は、因果的、時間的、または空間的である可能性があります。CEPには、高度なイベント解釈器、イベントパターンの定義とマッチング、および相関技術の使用が必要です。CEPは、ビジネス上の異常、脅威、および機会を検出して対応するためによく使用されます。[ 10 ]
オンラインイベント処理(OLEP)は、非同期分散イベントログを使用して複雑なイベントを処理し、永続データを管理します。[ 11 ] OLEPは、異種システム間で複雑なシナリオの関連イベントを確実に構成できます。これにより、高いスケーラビリティを備えた非常に柔軟な分散パターンが可能になり、強力な一貫性が提供されます。ただし、処理時間の上限を保証することはできません。
イベント駆動型アーキテクチャは、非常に疎結合で分散性が高い。このアーキテクチャの優れた分散性は、イベントがほぼあらゆるものになり、ほぼどこにでも存在できることに起因する。イベント自体はその原因の結果について知らないため、このアーキテクチャは非常に疎結合である。例えば、玄関ドアが開いたときに情報を記録する警報システムがある場合、ドア自体は、ドアが開いたときに警報システムが情報を追加することを知らず、ドアが開いたことだけを知る。[ 10 ]
イベント駆動型アーキテクチャは、空間、時間、同期において疎結合であり、情報交換と分散ワークフローのためのスケーラブルなインフラストラクチャを提供します。しかし、イベントアーキテクチャは、イベント購読とパターンを介して、基盤となるイベントスキーマと値のセマンティクスに密接に結合しています。スマートシティやセンサーウェブなどの大規模でオープンな展開におけるイベントのセマンティックな異質性の高さは、イベントベースシステムの開発と保守を困難にしています。イベントベースシステム内のセマンティック結合に対処するために、イベントの近似セマンティックマッチングの使用は活発な研究分野となっています。[ 12 ]
EDAにおける同期トランザクションは、リクエスト・レスポンスパラダイムを使用することで実現でき、2つの方法で実装できます。[ 1 ]
イベント駆動型アーキテクチャは分散コンピューティングの誤謬に陥りやすく、ソフトウェア開発やデプロイメントにおいて重大な問題を引き起こす可能性のある一連の誤解が生じる。[ 1 ]
イベントの数の適切なバランスを見つけるのは非常に難しい場合があります。詳細なイベントを生成しすぎると、システムが過負荷になり、イベント全体の流れを効果的に分析することが難しくなります。ロールバックが必要な場合は、この課題はさらに大きくなります。逆に、イベントを過度に統合すると、イベントコンシューマーからの不要な処理と応答につながる可能性があります。最適なバランスを実現するために、Mark Richards は、各イベントの影響と、コンシューマーがアクションを決定するためにイベント ペイロードを確認する必要があるかどうかを考慮することを推奨しています。たとえば、コンプライアンス チェックのシナリオでは、準拠と非準拠の 2 種類のイベントのみを公開すれば十分かもしれません。この方法により、各イベントは関連するコンシューマーによってのみ処理され、不要なワークロードが削減されます。[ 1 ]
イベント駆動型アーキテクチャを使用する際の課題の1つは、エラー処理です。この問題を解決する1つの方法は、独立したエラーハンドラプロセッサを使用することです。イベントコンシューマがエラーを経験すると、エラーイベントを即座に非同期でエラーハンドラプロセッサに送信し、処理を続行します。エラーハンドラプロセッサはエラーを修正し、イベントを元のチャネルに返送します。ただし、エラーハンドラプロセッサが失敗した場合は、エラーイベントを管理者に送信してさらに調査させることができます。エラーハンドラプロセッサを使用する場合、エラーイベントは再送信時に順不同で処理されることに注意してください。[ 1 ]
イベント駆動型アーキテクチャを使用するもう1つの課題は、データ損失です。コンポーネントのいずれかが、イベントを正常に処理して次のコンポーネントに渡す前にクラッシュした場合、イベントは破棄され、最終的な宛先に到達しません。データ損失の可能性を最小限に抑えるには、転送中のイベントを永続化し、次のコンポーネントがイベントの受信を確認したときにのみイベントを削除/デキューすることができます。これらの機能は通常、「クライアント確認モード」および「最終参加者サポート」として知られています。[ 1 ]