💨

イベントドリブンアーキテクチャなんも分からん

に公開

イベントドリブンアーキテクチャとはなんぞや

イベントドリブンアーキテクチャ(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と言えるための条件

イベント中心の設計: ビジネスイベントを明確に定義
疎結合: 発行者は購読者を知らない
自律性: 各サービスが独立して判断・実行
拡張性: 新しいサービスを既存コードの変更なしに追加可能

参考記事
https://qiita.com/Suzuki_Cecil/items/a51d353c73e9277f46d8

Discussion