イベント駆動アーキテクチャとは:イベント、コマンド、配信保証の違い
執筆:Ai Flowi · 公開日
イベント駆動アーキテクチャとは、プロデューサーが起きた事実を公開し、コンシューマーがその事実に反応する設計です。両者は、その間にイベント配信の仕組みを置くことで、別々に動作できます。この設計には、識別、順序、障害に関する明確なルールが必要です。通知を送るだけで、信頼できる処理が成立するわけではありません。
イベントは「これが起きた」を表します。コマンドは「これを実行してください」を表し、リクエストは特定のサービスからの直接の応答を期待する場合があります。この意味を区別すると、コンシューマーが観測結果を報告しているのか、実行を許可するかどうかを判断しているのかが明確になります。
イベントベースのアーキテクチャは何で構成されますか?
プロデューサーは変更を観測するか完了させ、イベントを作成します。配信の仕組みが、そのイベントを関係するコンシューマーに届けます。各コンシューマーは独自の処理ルールを適用し、結果を記録します。ブローカーを配信の仕組みに含めることはできますが、ブローカー自体がイベントの定義ではなく、この例でもブローカーの存在は前提にしていません。
プロデューサー:文書が承認された
↓
イベントエンベロープ + 承認済み文書への参照
↓
配信の境界
├─ コンシューマーA:業務用ビューを更新する
└─ コンシューマーB:後続対応の意図を記録する「文書が承認された」のような事実を表す名前は、承認が行われた後にのみ使います。「文書を承認してください」は、拒否されることもあるコマンドです。コマンドを完了済みのイベントとして公開すると、実際には行われていない承認を前提にコンシューマーが動作するおそれがあります。また、プロデューサーは、そのイベントが何を証明するかを正確に示す必要があります。承認の保存、承認の依頼、承認受領通知の送信は、それぞれ異なる観測結果です。
この記事独自のイベントエンベロープ例です。画面が狭い場合は、表の領域にフォーカスを移し、横にスクロールしてください。
| フィールド | 意味 | 守るべき境界 |
|---|---|---|
| event_id | synthetic-approval-Aなど、この事象を一貫して識別する値です。 | 同じイベントの再配信では再利用し、新たな承認には使いません。 |
| occurred_at | プロデューサーが承認の事実を記録した時刻です。 | 発信元の時計の文脈を保持します。到着時刻とは異なる場合があります。 |
| received_at | このコンシューマーが今回の配信を受信した時刻です。 | 後の配信では受信時刻も後になりますが、事象は同じです。 |
| event_type | この架空の契約ではdocument.approvedです。 | 未実行の指示ではなく、事実を表します。 |
| schema_version | エンベロープとペイロードの意味を定めるバージョンです。 | コンシューマーが解釈できないバージョンは拒否するか、確認対象にします。 |
| payload | 文書の識別情報、承認済みリビジョン、承認への参照です。 | 許可されたデータと、反応に必要な証拠だけを含めます。 |
配信保証の範囲は業務上の保証より狭いものです
最大1回の配信では、再配信を避ける代わりに欠落を許容します。少なくとも1回の配信では、定められた条件の下で最終的な到着を目指す一方、再配信を許容します。どちらの表現も、それだけではコンシューマーが業務上の書き込みを厳密に1回だけ行うことを証明しません。配信保証がどの境界を対象とし、確認応答が失われたときに何が起きるかを確認してください。
順序にも適用範囲が必要です。ある文書のイベントは順序付けされていても、無関係な文書は独立して進行する場合があります。全体の受信順序は、業務上の変更が起きた順序を証明しません。厳密に1回の動作をうたうシステムには、正確な適用範囲と障害モデルが必要です。証拠なしに、その表現をあらゆる外部の副作用に広げることはできません。
重複配信と、書き込み後の障害を考える
コンシューマーAはsynthetic-approval-Aを受信し、承認済みリビジョンを保存先に書き込んだ後、配信への確認応答を返す前に停止します。プロデューサーや配信の仕組みは書き込みの完了を判断できないため、同じイベントが再び届きます。コンシューマーが無条件に追記すると、承認は1回しかなかったにもかかわらず、2件目のレコードが作られます。
冪等な反応では、同じイベントを再処理しても、意図した効果が得られます。そのためには、再試行回数のカウンターだけでなく、業務上の識別情報と更新ルールが必要です。コンシューマーは、保存先での処理の効果とともにイベントの識別情報を保持するか、効果の重複を防ぐことが検証済みの契約で保証される保存先の操作を使えます。「確認済みイベント」を別途検索してから書き込む方法では、2つのコピーが同時に届くと、依然として競合が起こり得ます。
イベントの識別情報と、配信試行の識別情報は区別してください。再試行のたびに新しいevent_idを付けると、重複検出が機能しなくなります。逆に、実際に新たな承認が行われたのに古い識別情報を再利用すると、必要な処理が抑止される場合があります。この区別を管理するのはプロデューサーです。コンシューマーは、同じイベント識別情報に対してペイロードが食い違う場合、無害な再配信として黙って扱わず、問題として報告する必要があります。
2つのコンシューマーで順序の適用範囲を比較する
遅れて届いた状態の判断例は、顧客ライフサイクルのガイドで扱います。ここでは、どの受信順序が、プロデューサーの宣言した順序の適用範囲を満たすかを考えます。
プロデューサーPが文書AについてA1、次にA2を発行し、無関係な文書BについてB1を発行したとします。この架空の契約では、各文書内に順序を割り当てますが、文書間の順序は約束しません。コンシューマーXはA1、B1、A2の順に受信します。コンシューマーYはB1、A2、A1の順に受信します。両者の到着履歴は異なりますが、文書A内の順序に違反するのはYだけです。
| コンシューマーの観測 | 契約との比較 | 許容される判断 |
|---|---|---|
| X:A1、B1、A2 | A1がA2より先です。BはAの適用範囲外です。 | 各文書の順序を独立して処理します。 |
| Y:B1、A2、A1 | A2が、必要な先行イベントA1より前に届きます。 | A2の依存する反応を保留します。B1は進められます。 |
| Y:後からA1を受信 | 欠けていた先行イベントを利用できるようになりました。 | コンシューマーの処理ルールに従い、A1、次に保留中のA2を評価します。 |
| A2がプロデューサーQを名乗る | Pの順序ではQの順序を証明できません。 | 順序を統合する前に、プロデューサー間の契約を求めます。 |
この保留方針は、この記事で定めたコンシューマーの要件であり、プラットフォームの機能を示すものではありません。先行イベントを受信していても、処理が成功済みとは限りません。A1への反応が失敗し、A2のルールがその反応に依存する場合、A2は引き続き停止したままです。独立した監査上の事実を記録するだけのコンシューマーでは、依存関係が異なる場合があります。そのため、配信順序と処理順序は別々に定義する必要があります。
途中のすべての番号がこのコンシューマーのストリームに属すると順序契約で定められていない限り、番号の欠けだけからイベントの欠落を推測しないでください。フィルタリングによって、特定のイベント種別が意図的に除かれる場合があります。順序番号の範囲が1つの文書、1つのプロデューサー、フィード全体のどれなのか、またコンシューマーが欠落したレコードを取得できるかを記録してください。そうしないと、何の証拠があれば解除できるか分からないまま、保留が続くおそれがあります。
AI Flowi Workflowにおける具体的な信頼性の境界
状態:リンク先のWebhook信頼性レシピに記録された範囲でテスト済みです。Webhookのエラー処理ページでは、同じevent_idの5件の同時配信はすべて200を返し、シートに3行を追加した
と報告されています。HTTPステータスの確認では5件中5件の応答が成功しましたが、1つのイベントが3行になり、一意性の要件は満たされませんでした。これは実測された並行処理の制約であり、厳密に1回の処理の証拠ではありません。
リード獲得のレシピには、順次繰り返した場合は同じ行が更新され、2行目は追加されないと記載されています。そのコンポーネントの並びは、特定のレシピについての証拠であり、ブローカーやストリーミングプラットフォームの証拠ではありません。この信頼性の例は、順次処理での重複確認を、同時配信の保証に拡大してはいけない理由を示しています。
エンベロープの表現に使うインターフェースについては、JSON Object BuilderとJSON Operationsを参照してください。この提案用途は、カタログに記載されていますが、Ai Flowiによる本番環境でのテストは行われていません。
構成例であり、記録されたテストではありません。JSON Object Builderのfield_namesには、表にある6つのエンベロープフィールドを指定します。順序契約で必要な場合は、作成するペイロード内にproducer_id、document_id、document_sequenceを入れます。生成したレコードは順序の証拠を持てますが、その解釈にはコンシューマーの方針が依然として必要です。JSONを生成しても、順序付きキューやコンシューマーのアトミックなチェックポイントは実装されません。
よくある間違いと関連用語
指示を事実と呼ぶこと、結果不明の状態を捨てること、到着順序を業務上の順序として使うこと、1つのコンシューマーが応答しただけで全コンシューマーの成功を想定することは避けてください。同じ識別情報の再配信、ペイロードの矛盾、遅れて届くリビジョン、保存先への書き込み後の障害は、別々のシナリオとしてテストします。各観測結果がどの境界を対象とするかを記録してください。
ワークフローオーケストレーションは、連携した作業内の依存関係と復旧状態を扱います。APIゲートウェイは、入口でのルーティングとポリシーを扱います。Universal Webhookのリファレンスは、特定のHTTP受付の仕組みを説明するものであり、アーキテクチャの配信契約に代わるものではありません。