イベント駆動型マイクロサービスアーキテクチャでの変更の処理


9

イベント駆動型マイクロサービスアーキテクチャの変更を処理するためのオプションを調査している調査プロジェクトを行っています。

したがって、4つの異なるサービスを利用できるアプリケーションがあるとします。これらの各サービスには、ローカルデータを格納するための独自のデータベースがあります。

このセットアップでは、4つのサービスがイベントバスを使用して相互に通信します。したがって、サービスで何かが発生すると、イベントが発行されます。そのイベントに関心のある他のすべてのサービスは、独自の方法で処理します。

その場合、アーキテクチャー内のさまざまなサービスは、これらのイベントの内容(属性など)について「契約」を持つ必要があります。したがって、サービスはこれらのイベントに「疎結合の依存関係」を持っています

私の質問は次のとおり です。これらのイベントの変更をどのように処理できますか?

それでは、サービスAがアプリケーションに新しいユーザーを登録するとします。したがって、 "" UserRegistered "イベントを送信します。サービスBがそのイベントを取得して処理します。ただし、サービスチームCの一部の開発者は、登録済みユーザーの性別も必要であると判断しました。そのため、イベントが変更され、属性gender 「UserRegistered」イベントに追加されます。

サービスBが再デプロイせずに、その追加属性を使用して同じイベントを引き続きピックアップできることをどのように確認できますか?

そして、この問題に取り組み、これらのイベントをバージョン管理する他の方法はありますか?


あなたのメッセージはどのようなフォーマットですか、それともあなたがデザインできるものですか?一部のメッセージ形式では、オプションの属性を使用できます。リーダーの実装によっては、すべてのリーダーを更新する必要なく、オプションの属性を追加できます。
トーマス・オーエンス

メッセージに使用する形式を自由に選択できます。JSONを使用するのが最善の方法だと思います。これらのさまざまなサービスがさまざまな言語で構築されていることが重要です。そのため、XMLやJSONなどの一般的な形式が必要です。
CGeense 2016

回答:


1

イベントは何が変わったのかではありません。何かが変わったときのことです。

変化した内容から完全に切り離されたイベントシステムを作成できます。その方法で私がイベントから学ぶすべては、オブジェクトが更新されたことです。オブジェクトが更新されていることさえ気になっている場合は、そのオブジェクトと対話して変更点を尋ねる方法を知っている人には何でも伝えます。

それはこれらの変更を伝える問題を解決しません。イベントシステムの一部になるのを止めるだけです。

異なるバージョンのデータの問題を解決する1つの方法の例は、オブザーバーに監視対象オブジェクトを作成してコレクションを渡すことです。監視対象オブジェクトは、コレクションに最新のデータを入力し、コントロールが戻ったときに(オブザーバー)が必要なものを持っています。あなたがそれを聞いたことがないので、あなたが気にしない余分なものがあれば、あなたは単にそれを無視します。

その猫の皮をむく他の多くの方法がありますが、それは私がまさにこの場合に機能させたものです。


これはサービス間のトラフィックを劇的に増加させませんか?質問の例でUserRegisteredあるイベントを使用すると、ユーザーに関する情報が含まれていないイベントがあった場合、バスへの1つの公開メッセージがあり、次にユーザーサービスまたは公開メッセージへの{number of Interesting services}リクエストがあります。バスに。次に、さまざまなサイズの{関心のあるサービスの数}メッセージが返されます。これはおそらく紙の上でよりすっきりしたデザインだと思いますが、パフォーマンスが懸念される場合は、特にネットワーク上の重要なシステムでは機能しません。
Thomas Owens

@ThomasOwensイベントでデータを送信するということは、N人のオブザーバーがいる場合、N個のメッセージを送信することを意味します。イベントのみを送信するということは、3Nメッセージを送信することを意味します。そのうちの1つだけにデータパケットがあります。これはネットワーク上でも問題なく拡張できます。唯一の重大な欠点は、ラグが3倍になることです。特定の状況に最適なソリューションを見つけることができないと言っているのではありません。イベントシステムとデータバージョンを結合する必要がないことを示しています。
candied_orange 2016

1
このイベントバスの全体的なアイデアは、さまざまなサービスを分離することです。ミドルウェアを使用することで、これらのサービスがお互いを知らず、存在し、お互いの存在を知らなくても通信できることを確認できます。これらのイベントから状態を削除し、サービスを相互に直接接続させると、これらのサービスが結合されます。このようにして、残りのサービスを再デプロイすることなく、単一のサービスを再デプロイすることはできません
CGeense

1
ここでのポイントは、そのイベントシステムであるかどうかにかかわらず、拡張可能なデータが必要です。以前に確立された名前や構造を変更しない場合、JSONまたはXMLはそれで十分です。コレクションについても同じことをしました。イベントシステムは性別を気にするべきではありません。データを送信している場合は、それらを渡すだけで、もう一方の端の何かが性別を気にするか、気にしません。
candied_orange 2016

1

NServiceBusのようなフレームワークは、ポリモーフィックメッセージディスパッチでイベントのバージョン管理を使用してこれを処理します。

たとえば、サービスAのバージョン1は、イベントをIUserRegistered_v1として発行します。サービスAバージョン1.1が追加フィールドを含める必要がある場合、それはインターフェースIUserRegistered_v1_1を宣言する可能性があります。これは、IUserRegistered_v1から継承し、いくつかの追加フィールドを宣言します。

サービスAがIUserRegistered_v1_1イベントを発行すると、NServiceBusはIUserRegistered_v1またはIUserRegistered_v1_1を処理するすべてのエンドポイントにメッセージをディスパッチします。


0

漸進的改善

モデルへの簡単な変更は、リスナーがオブザーバーとして登録するときに、知りたいデータ要素のリストまたは他の構造を含めることです。これは、サービスから返されるデータが単純な場合は機能しますが、階層データが大量にある場合は、実装が非常に複雑になる可能性があります。

堅実

これを行うための堅牢な方法が本当に必要な場合は、格納するデータに加えられた変更の履歴を保持するようにサービスを設計してください。基本的に、データベースのレコードを更新するのではなく、それぞれが変更を表す新しいレコードを追加します。これらの新しいレコードはそれぞれ、アクションを識別するイベントIDに関連付けられています。変更に関するすべての関連情報(だれが、何を、いつなど)とともに偶数レコードが保存されます。これには、この回答の範囲外のいくつかの利点がありますが、CAP定理に関するこの記事で説明されています

変更が加えられたら、イベントレコードを作成し、すべての新しいデータをデータベースに追加します。次に、イベントIDを(少なくとも)含むリスナーにイベントを発行します。その後、リスナーはそのIDに関連付けられたデータを要求し、それに関連付けられたデータのバージョンを取得できます。各リスナーは、他の異なるリスナーのニーズを結合することなく、必要なものをすべて取得できます。リスナーが関心のないイベントをフィルターで除外できるように、最もよく使用されるデータフィールドのサブセットをイベントメッセージに追加することをお勧めします。これにより、プロセスの雑談を減らすことができ、一部のリスナーは呼び出す必要がない場合があります全然戻った。これにより、タイミングの問題からも保護されます。サービスにコールバックし、キーに基づいてデータを取得する場合、イベントを取得してからそのデータを取得するまでの間に他の変更が発生した可能性があります。これはすべてのリスナーにとって重要ではないかもしれませんが、すべての変更について知る必要がある場合、大きな問題を引き起こす可能性があります。上記の増分設計の改善は、本当に11にしたい場合、このアプローチと互換性があります。

これの一部は、あなたがする必要があることに対してはやり過ぎかもしれませんが、私の経験では、レコードが時間の経過とともにどのように変化するかを調べる正確な方法がない場合、あなたやデータを扱う誰かが最終的にそれを必要とするでしょう。


-1

@CandiedOrangeは、xmlのような拡張可能なデータ形式に関する彼自身の回答へのコメントで有効なポイントを示しています。

データを追加している限り、問題はありません。ただし、古いイベント/必須でないフィールドには適切なデフォルトを提供してください。

気になるサービス(この場合はGender)のみを更新する必要があります。xml / jsonパーサーは、他のサービスの余分なデータを無視できるはずです。もちろん、これは選択したパーサーとイベントデータ形式によって異なります。

ただし、関連データがないイベントには同意しません。イベントソースの場合、イベントは変更点を定義する必要があります。イベントの受信時に、他のサービスはイベントのソースからデータを取得する必要はありません。


私のポイントは、あらゆる種類の変更を処理する必要があるということです。イベントをブロードキャストするサービスを考えてみてください。また、そのイベントには廃止されたプロパティが含まれているため、削除する必要があります。これらの他のサービスがプロパティを使用していない場合でも、それを期待しているという理由だけでサービスが停止します。ですから、消費者主導の契約についてmartinfowler.comでこの記事を読みます: martinfowler.com/articles/consumerDrivenContracts.html この原則を適用するとき。各プロバイダー(イベント)は、彼に何が期待されるかを知っています。その情報により、彼は消費者を破ったかどうかを検証できます。
CGeense 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.