イベント駆動型マイクロサービスアーキテクチャの変更を処理するためのオプションを調査している調査プロジェクトを行っています。
したがって、4つの異なるサービスを利用できるアプリケーションがあるとします。これらの各サービスには、ローカルデータを格納するための独自のデータベースがあります。
このセットアップでは、4つのサービスがイベントバスを使用して相互に通信します。したがって、サービスで何かが発生すると、イベントが発行されます。そのイベントに関心のある他のすべてのサービスは、独自の方法で処理します。
その場合、アーキテクチャー内のさまざまなサービスは、これらのイベントの内容(属性など)について「契約」を持つ必要があります。したがって、サービスはこれらのイベントに「疎結合の依存関係」を持っています
私の質問は:これらのイベントの変更をどのように処理できますか?
したがって、サービスAがアプリケーションに新しいユーザーを登録するとします。したがって、 "" UserRegistered "イベントを送信します。サービスBがそのイベントを取得して処理します。ただし、サービスチームCの一部の開発者は、登録済みユーザーの性別も必要であると判断しました。そのため、イベントが変更され、属性gender 「UserRegistered」イベントに追加されます。
サービスBが再デプロイせずに、その追加属性を使用して同じイベントを引き続きピックアップできることをどのように確認できますか?
そして、この問題に取り組み、これらのイベントをバージョン管理する他の方法はありますか?
NServiceBusのようなフレームワークは、ポリモーフィックメッセージディスパッチでイベントのバージョン管理を使用してこれを処理します。
たとえば、サービスAのバージョン1は、イベントをIUserRegistered_v1として発行します。サービスAバージョン1.1が追加フィールドを含める必要がある場合、インターフェースIUserRegistered_v1_1を宣言する場合があります。これは、IUserRegistered_v1から継承し、いくつかの追加フィールドを宣言します。
サービスAがIUserRegistered_v1_1イベントを発行すると、NServiceBusはIUserRegistered_v1またはIUserRegistered_v1_1を処理するすべてのエンドポイントにメッセージをディスパッチします。
イベントは何が変わったのかではありません。彼らは何かが変わったときのことです。
変化した内容から完全に切り離されたイベントシステムを作成できます。その方法で私がイベントから学ぶすべては、オブジェクトが更新されたことです。オブジェクトが更新されていることさえ気になっている場合は、そのオブジェクトと対話して変更点を尋ねる方法を知っている人に伝えます。
それはこれらの変更を伝える問題を解決しません。イベントシステムの一部になるのを止めるだけです。
異なるバージョンのデータの問題を解決する1つの方法の例は、観察者に観察対象のオブジェクトを作成してコレクションに渡すことです。監視対象オブジェクトは、コレクションに最新のデータを入力し、コントロールが戻ったときに(オブザーバー)が必要なものを持っています。あなたがそれを聞いたことがないので、あなたが気にしない余分なものがあれば、あなたは単にそれを無視します。
その猫の皮をむく方法は他にもたくさんありますが、これはまさにこのケースで機能させた方法の1つです。
モデルへの簡単な変更は、リスナーがオブザーバーとして登録するときに、知りたいデータ要素のリストまたは他の構造を含めることです。これは、サービスから返されるデータが単純な場合は機能しますが、階層データが大量にある場合は、実装が非常に複雑になる可能性があります。
これを行う堅牢な方法が本当に必要な場合は、格納するデータに加えられた変更の履歴を保持するようにサービスを設計してください。基本的に、データベースのレコードを更新するのではなく、それぞれが変更を表す新しいレコードを追加します。これらの新しいレコードはそれぞれ、アクションを識別するイベントIDに関連付けられています。変更に関するすべての関連情報(誰が、何を、いつなど)を含む均一なレコードが保存されます。これには、この回答の範囲外である他のいくつかの利点がありますが、これについては CAPに関する記事)定理 。
変更が加えられたら、イベントレコードを作成し、すべての新しいデータをデータベースに追加します。次に、イベントIDを(少なくとも)含むリスナーにイベントを発行します。その後、リスナーはそのIDに関連付けられたデータを要求し、それに関連付けられたデータのバージョンを取得できます。各リスナーは、他の異なるリスナーのニーズを結合することなく、必要なものをすべて取得できます。リスナーが関心のないイベントをフィルターで除外できるように、最もよく使用されるデータフィールドのサブセットをイベントメッセージに追加することをお勧めします。これにより、プロセスの雑談を減らすことができ、一部のリスナーは呼び出す必要がない場合があります全然戻った。これにより、タイミングの問題からも保護されます。サービスにコールバックし、キーに基づいてデータを取得するだけの場合、イベントを取得してからそのデータを取得する間に他の変更が発生している可能性があります。これはすべてのリスナーにとって重要ではないかもしれませんが、すべての変更について知る必要がある場合、大きな問題を引き起こす可能性があります。上記の増分設計の改善は、本当に11にしたい場合、このアプローチと互換性があります。
これの一部は、あなたがする必要があることに対してはやり過ぎかもしれませんが、私の経験では、レコードが時間の経過とともにどのように変化するかを調べる正確な方法がない場合、あなたやデータを扱う誰かが最終的にそれを必要とするでしょう。