web-dev-qa-db-ja.com

複数のサービス用のイベント駆動型アーキテクチャーの設計

イントラネット用に約12のサービスを作成しました。これらのサービスは、自分が使い慣れているよりも互いに結合しているという点に到達しました。一度サービスを実行すると、他のいくつかのサービスが低下する可能性があるという問題が発生しています。

これらのサービスを互いに分離できるように、EDAの設計に取り組んでいますが、私はここで唯一のプログラマーなので、フィードバックが必要です。

この設計は、次のシナリオを解決することを目的としています。

シナリオ1:クライアントがサービスAにデータを要求し、その要求を満たすためにサービスAにはサービスBからのデータが必要ですが、サービスBは失敗して応答しません

シナリオ2:クライアントがサービスBのエンティティを更新し、このエンティティへの参照をサービスAおよびCで更新する必要がある

デザインを2つの部分に分割しましたOperationsおよびEvents

operationは、サービス内のエンティティを変更するためにサービスまたはクライアントによって送信されます。これにより、常にイベントが発生します。各操作には、ユーザーID、操作ID、およびいくつかのタイムスタンプが含まれています。

eventは操作に対する反応であり、変更を発生していることを聞いている人に通知します。各イベントには、それを開始した操作のID、それを引き起こしたユーザーのID、およびいくつかのタイムスタンプが含まれています。各イベントには完全なエンティティのハッシュも含まれるため、リスナーはバージョンと比較できます。

私はメッセージバスとしてRabbitMQを使用しており、各サービスには保留中のイベントや操作を保存するための永続的な永続キューがあります。

サービスを互いに分離するために、各サービスは、別のサービスに属するエンティティが依存しているエンティティをキャッシュします。

サービスが別のサービスのエンティティを必要とする場合、それをフェッチして、データベースのテーブルに格納します。次に、キャッシュ内のエンティティに加えられた変更をリッスンし、それに関連するイベントが発生したときにそれらを更新します。

キャッシュからのエンティティの保存またはフェッチが失敗すると、適切なサービスからエンティティを再フェッチします。

監査には、すべてのサービスからのイベントをリッスンして保存するサービスがあります。その後、任意の時点で任意のエンティティを再作成できます。

私よりも経験豊富な人からのコメントや、デザインに重大な問題があるかどうかを知りたいです。

6
grimurd

指摘したいことがいくつかあります。

  1. operationsの代わりにcommandsを参照します。それはあなたがモデリングしているシステムの周りの専門用語にぴったりだと思います。
  2. イベントをトリガーとして使用して、他のサービスからデータを取得しているようです。イベントを使用して、そもそもそれらのエンティティを作成しますか?その場合は、公開するイベントを格納するために、各アプリケーションに何らかの形式のEventStoreを導入することを強くお勧めします。その後、これらのイベントを再利用して、必要に応じてエンティティを再作成できます。ほとんどの人はこれをイベントソーシングと呼んでいますが、私はその用語をアプリケーションの書き込み側(例では「操作処理」)に使用することを好みます。それでも、これらのイベントであなたのエンティティも作成します。このアプローチをとれば、他のサービスにそれらのすべてのイベントをリッスンさせ、必要なエンティティを作成させることもできます。これにより、エンティティをクエリする必要がなくなります。
  3. 監査用に別のサービスを追加すると指摘しました。ポイント2からの提案に従っている場合、イベントストアは自動的に監査ログにもなります。これはもちろん、イベントを正しくモデル化した場合にのみ当てはまりますが、それでも、イベントをファーストクラスの市民にして、公開後すぐに保存することは、専用の監査ログサービスを必要としないと思います。
  4. 使用しているプログラミング言語がわからない場合でも、たとえば Axon Framework などのCQRS/EDA/DDDフレームワークを調べてみることをお勧めします。これはJavaに基づいていますが、Javaを使用していない場合でも、フレームワークがあなたを助けようとする概念は、あなたがやろうとしていることに似ています。

全体として、アプリケーションセットを提案したようなものに改造することは良いことだと思います。通信メッセージをベースにし、サービスの場所を透過的にすることで、現時点で心配している結合を確実に失うことができます。

2
Steven

まず、サービスAがサービスBからのデータを必要とする場合、サービスの境界が間違っています。システムを分割するために使用した基準はエンティティによるもののようです。これは、すでに 2007年に悪と考えられていた である階層化サービスの概念と相関しています。

私が提唱しているアプローチは、ビジネス能力の概念に基づいています。ドメイン内で、非常にまとまりのある領域を特定します。これらの領域は、その領域内でのみ使用されるいくつかのカプセル化されたデータ、そこで実装されているビジネスプロセス、アプリケーション、および人々で構成されます。次に、それらの領域を深く掘り下げ、そのステップを繰り返します。 値連鎖分析 を使用すると便利です。ビジネスプロセスを準備することを検討してください。どのようにお金を稼ぎますか、あなたのビジネスの存在の主な理由は何ですか?このプロセスを一連のステップとして見てください。一部のステップに他のステップと接続されていないビジネスプロセスが含まれている場合、おそらくこれらのステップはスタンドアロンサービスである可能性があります。

テクニカルサービスは、これらのビジネスサービスに1対1で対応します。

SOAに関する一連の投稿 にも例が含まれていますので、チェックしてください。

2
Zapadlo