イベントドリブンアーキテクチャなんも分からん
イベントドリブンアーキテクチャとはなんぞや
イベントドリブンアーキテクチャ(Event-Driven Architecture、EDA)は、イベント(出来事や状態変化)の発生をトリガーにして、システムの各部分が非同期に反応・動作する設計パターン
うーん分からん。従来の方式と比較して整理する。
Request-Reply方式の場合
clientがrequestを送信
serverがrequestを処理
serverがreplyを返信
clientがreplyを受け取る ※replyを受け取るまでの間はclientは待機する
- 同期的な通信: クライアントは通常、応答が返ってくるまで待機します
- 1対1の対応: 1つのリクエストに対して1つのリプライが返されます
- シンプルで分かりやすい: 最も基本的な通信パターンです
EDAの場合
publisher(従来のclientに相当)はとあるイベントを発生させるだけ、subscriber(従来のserverに相当)はとあるイベントが発生したときに自身の処理を行うだけ。
- 疎結合: 各コンポーネントは互いに直接依存せず、イベントを介して通信します。サービス同士が誰が誰を呼び出すかを知る必要がありません。
- 非同期処理: イベントの発行者は、処理の完了を待たずに次の処理に進めます。
- スケーラビリティ: 各サービスを独立してスケールできます。
- 柔軟性: 新しいサービスを追加する際、既存のコードを変更する必要が少なくなります。
↑の文章を見ても、スケーラビリティと柔軟性の部分がイメージ湧かなかったので補足説明もメモっておく。
補足1 スケーラビリティについて
従来の同期的なアーキテクチャ
ユーザー → 注文API → 在庫API → 決済API → メールAPI
- 注文APIは全ての処理が完了するまで待つ必要がある
- メールAPIが遅いと、注文API全体が遅くなる
- 負荷が高いとき、全てのサービスを一緒にスケールする必要がある
EDAの場合
注文API → イベント発行 → 終了(高速)
↓
[イベントバス]
↓→ 在庫サービス(普通の負荷)
↓→ 決済サービス(高負荷)× 10インスタンス
↓→ メールサービス(低負荷)
- 注文APIはイベントを発行したらすぐ終了できる
- 決済サービスだけ負荷が高い場合、そのサービスだけを10倍にスケール
- メールサービスは1インスタンスで十分なら、そのままコストを最適化できる
なぜこの違いが生まれるのか
密結合 vs 疎結合の違いです:
- 従来: 注文サービスが「誰を呼ぶか」を知っている(密結合)
- EDA: 注文サービスは「何が起きたか」を伝えるだけ(疎結合)
疎結合だからこそ:
各サービスが独立して動作できる → スケーラビリティ
補足2 柔軟性について
従来のアーキテクチャで機能追加
要件: 注文時にポイントを付与したい
注文サービスのコード:
function createOrder() {
validateStock(); // 既存
processPayment(); // 既存
sendEmail(); // 既存
addPoints(); // ← 新規追加(コード変更必要)
}
- 既存コードの修正が必要
- 再デプロイが必要
- テストをやり直す必要がある
- ポイントサービスの障害が注文全体に影響
EDAの場合
注文サービス(変更なし):
function createOrder() {
publishEvent("OrderCreated"); // これだけ
}
新しいポイントサービス(独立して追加):
subscribe("OrderCreated", function(event) {
addPoints(event.userId);
});
- 既存コードは一切触らない
- 新しいサービスを追加するだけ
- 既存サービスの再デプロイ不要
- ポイントサービスの障害は注文処理に影響しない
なぜこの違いが生まれるのか
密結合 vs 疎結合の違いです:
従来: 注文サービスが「誰を呼ぶか」を知っている(密結合)
EDA: 注文サービスは「何が起きたか」を伝えるだけ(疎結合)
疎結合だからこそ:
各サービスを独立して追加・変更できる → 柔軟性
補足3 メッセージキューやpub/subの採用 = EDA?
メッセージキューやPub/Subを使うことは、イベントドリブンアーキテクチャを実現するための手段ですが、それだけでは必ずしもEDAになるとは限らない。
メッセージキューを使っていても、以下のような場合はEDAとは言えない。
サービスA → キュー → サービスB(必須の処理)→ キュー → サービスC(必須の処理)
これは単に「非同期化された直列処理」で、依然として密結合。サービスAはBとCが存在することを前提としている。
EDAと言えるための条件
イベント中心の設計: ビジネスイベントを明確に定義
疎結合: 発行者は購読者を知らない
自律性: 各サービスが独立して判断・実行
拡張性: 新しいサービスを既存コードの変更なしに追加可能
参考記事
Discussion