arch-event-driven について
コンポーネント間の通信方式を検討する開発者向けの、イベント駆動設計スキルです。ブローカーとメディエーターの構成、コレオグラフィとオーケストレーション、ブローカー選択やイベントスキーマの管理を扱います。
主な機能
- 01ブローカーとメディエーターの構成
- 02イベントとコマンドの違い
- 03コレオグラフィとオーケストレーション
- 04ブローカーの選定指針
- 05イベントスキーマのバージョン管理
活用シーン
- 01疎結合コンポーネントの設計
- 02リアルタイムデータ処理パイプラインの構築
- 03ビジネスイベントワークフローの設計
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ yonatankarp/ software-design-skills --skill arch-event-drivenインストール後、Claude Code で/arch-event-drivenを入力して読み込まれたか確認します。
詳細
1行でまとめると
コンポーネントは互いに直接呼び出すのではなく、ブローカーを介してイベントを発行し、反応することで通信します。プロデューサーは誰がコンシューマーなのかを把握せず、コンシューマーも誰がプロデューサーなのかを把握しません。
このスキルを使う場面
- 独立してスケールさせる必要がある、疎結合なコンポーネント。
- リアルタイムのデータ処理、ストリーミング、分析パイプライン。
- 「Xが発生したら、Yが反応する」という流れが自然なビジネスワークフロー。
- プロデューサーに知らせることなく、下流のコンシューマーを追加または削除するシステム。
このスキルを使わない場面
- 厳密なトランザクション整合性が必要な場合 — イベントは結果整合性です。
- 同期的なリクエスト/レスポンスが自然な通信形式の場合 — 非同期を無理に導入すると、遅延と複雑さが増します。
- ひとつのプロセス内に数個のコンポーネントだけが存在する小規模なシステム — イベントは過剰です。直接呼び出すほうがシンプルです。
主な内容
2つのトポロジー(Richards & Ford):
- ブローカートポロジー — コンポーネントがトピックにイベントを発行し、サブスクライバーがそれを消費します。中央のコーディネーターはいません。各ステップが小さな反応となる、振り付け型のワークフローに最適です。
- メディエータートポロジー — 中央のメディエーターがワークフローをオーケストレーションし、イベントプロセッサーにコマンドを送信します。手順が定められており、全体の流れを把握する必要がある場合に最適です。
イベントとコマンド。
- イベントは、すでに発生したことを過去形で表します(
OrderPlaced、PaymentSettled)。プロデューサーは事実を表明し、サブスクライバーは反応するかどうかを判断します。ddd-domain-eventを参照してください。ドメインイベントはモデルレベルでのこの概念であり、EDAでは同じイベントがブローカーを通じて流れます。 - コマンドは、何かを実行するための命令的な要求です(
PlaceOrder、SettlePayment)。特定のハンドラー1つを対象とします。イベントは複数の宛先に配信されますが、コマンドは1つを対象とします。
振り付けとオーケストレーション。
- 振り付け — コンポーネントがそれぞれ独立してイベントに反応し、各コンポーネントのローカルな判断から全体のワークフローが生まれます。分散型でスケールしやすい一方、全体像を把握しにくくなります。
- オーケストレーション — コーディネーター(メディエーター、サガ、ワークフローエンジン)が、各コンポーネントに次の処理を指示します。集中型で理解しやすい一方、複雑さが一箇所に集まります。
ブローカーの選択肢。
- 永続ログを持つトピック(Kafka):イベントを一定の保持期間にわたって保存し、サブスクライバーは再生できます。分析、監査、後から参加するコンシューマーに適しています。
- 配信保証付きのキュー(RabbitMQ、SQS):イベントは1回配信され、その後削除されます。ワークキューパターンに適しています。
- プロセス内バス(Springの
ApplicationEventPublisher):イベントは単一のJVM内にとどまります。低コストで、モノリス内部の疎結合に適しています。
スキーマの管理。 イベントスキーマは、イベント駆動システムの公開APIです。外部とのあらゆる契約と同じ厳密さでバージョン管理してください。後方互換性のある変更のみを行い、新しいフィールドにはデフォルト値を設定し、非推奨のフィールドはコンシューマーの移行が完了するまで残します。
判断の目安
- 手順が4つ以下(≤4)で参加者が安定しているワークフローには振り付けを使います。手順が増える場合や、補償処理が複雑な場合はオーケストレーションを使います。
- 実際に必要な要件に基づいてブローカーを選びます。再生が必要ならログベース、1回限りの配信ならキュー、プロセス内ならインメモリバスです。
- モノリス内でイベント駆動を採用する方法も有効です(プロセス内イベント)。EDAを導入するのにKafkaは必要ありません。
- 最初からスキーマレジストリと組み合わせてください。イベント駆動システムは、スキーマの変更が管理されないと、最も早く劣化します。
アンチパターン
- イベントを装ったコマンドによる「イベント駆動」(
UpdateOrderEvent)—余分なレイテンシーを加えただけのRPCです。過去形の名前を必ず使ってください。 - メソッド呼び出しとしてのイベント。 プロデューサーがイベントを発行し、特定のコンシューマーからの応答をすぐに待ち受けることは、非同期を装った同期RPCです。それが必要であれば、適切なリクエスト・レスポンス方式を使ってください。
- スキーマの混乱。 プロデューサーが調整なしにイベントのペイロードを変更します。コンシューマーは気づかないうちに壊れます。
- リプレイ戦略がない。 重要なイベントが失われても、復旧する方法がありません。ブローカーの保持期間は慎重に選んでください。
- 12段階のワークフローに振り付け型を使う。 全体を把握できる人がいなくなります。オーケストレーションに切り替えてください。
関連項目
arch-microservices— イベント駆動は、マイクロサービスにおける一般的な通信スタイルの1つです(もう1つはREST/gRPCです)。arch-saga— イベント/コマンドを介して分散トランザクションをオーケストレーションします。arch-event-sourcing— イベントを単なる通信手段ではなく、状態の信頼できる情報源とする場合に参照してください。arch-cqrs— EDAと併用されることがよくあります。書き込みによってイベントが生成され、読み取りではイベントから派生したマテリアライズドビューを参照します。ddd-domain-event— モデルレベルのイベント概念で、多くの場合、ワイヤーレベルのイベントになります。
参考文献
- Richards & Ford、『Fundamentals of Software Architecture』、第14章(イベント駆動アーキテクチャスタイル)。
- Adam Bellemare、『Building Event-Driven Microservices』(O'Reilly)。
- Khononov、『Learning DDD』、第15章(イベント駆動アーキテクチャ)。
コメント
Markdown 対応