web-dev-qa-db-ja.com

ビジネスロジックはマイクロサービスアーキテクチャのどこに配置する必要がありますか?

私はモノリシックなアプローチに慣れているので、マイクロサービスアーキテクチャに頭を抱えようとしています。

非常に簡略化された Uber予約システムを構築しようとしているとします。物事を簡単にするために、クライアントに3つのサービスとゲートウェイAPI BookingDriversNotificationがあり、次のワークフローがあるとします。

新しい予約を作成する場合:

  1. 既存のユーザーがすでに予約しているかどうかを確認する
  2. 利用可能なドライバーのリストを取得する
  3. ドライバーに通知を送信して予約をピックアップします
  4. 運転手が予約をピックアップ

すべてのメッセージングが、kafkaなどのメッセージングバスではなく、http呼び出しを介して行われるとしましょう。

したがって、この場合、Bookingサービスが既存の予約のチェックを実行できると思いました。しかし、利用可能なドライバと通知のリストを誰が取得する必要がありますか?ゲートウェイレベルで実行することを考えていますが、ロジックは次の2つの場所に分割されています。

  • Gateway-利用可能なドライバーのリストを取得+通知を送信
  • Booking-既存の予約を確認

そして、ゲートウェイはそれを行うのに適切な場所ではないと確信していますが、Bookingサービスでそれを行っている場合、緊密に結合されているように感じますか?

さらに複雑にするために、予約システムを再利用したいが、独自のビジネスロジックを上に置いた別のプロジェクトがある場合はどうなりますか?新しいプロジェクトゲートウェイが独自のビジネスロジックを既存のものから分離できるように、ゲートウェイレベルでそれを行うことを考えたのはそのためです。

それを行う別の方法は、各プロジェクトがコア予約サービスと通信する独自​​の予約サービスを持っていることですが、ここでの最善のアプローチは何なのかわかりません:-)

11
GantengX

人々はしばしば「マイクロサービス」を聞いて「ナノサービス」を考えます、そしてこれはいくつかの混乱を引き起こす可能性があります。これらはmicro-servicesなので、エンティティごとに個別のサービスを用意する必要はありません。あなたがしようとしているすべてがbookingnotificationサービスにあるはずです。 driverサービスは必要ありません(説明したアクティビティの場合)。

bookで利用可能なドライバのリストを取得することは、bookingサービスに該当します。一般的な落とし穴は、関連するアクティビティを同じサービスにグループ化しないことです。これは低コヒーレンスと呼ばれ、非常に悪いです。エンティティごとではなく、問題ドメインごとに物事をサービスにグループ化することを忘れないでください。

さて、再利用に関しては、個別のマイクロサービスを持つことの利点は、消費者向けのアプリを作成する3つの個別のチームを持つことができるようになったことです。 Androidアプリとiosアプリです。これらすべての異なるアプリケーションは、まったく異なる方法で構築でき、特定のプラットフォームに適しているように見えます(コードを繰り返す必要はありません)。 bookingサービスコードは、これら3つのアプリすべてで再利用されます。これは、3つのアプリすべてが独自の予約コードを持たずにサービスにhttp呼び出しを行うためです。

一般的な予約フローは次のようになります。

  1. Androidアプリはbookingサービスを呼び出して、利用可能なドライバーのリストを取得します
  2. 予約サービスはアプリにドライバーのリストを返します
  3. 次にユーザーはドライバーを選択し、アプリはbookingサービスの「book」メソッドを呼び出します
  4. bookingサービスサービスは、予約の詳細でnotificationサービスを呼び出します
  5. notificationサービスはドライバーに通知を送信し、予約をドライバーに通知します
  6. ドライバーアプリは、顧客から1マイル以内にいるときにnotificationサービスにメッセージを送信します
  7. notificationサービスは、ドライバーがもうすぐそこにいるというアラートを顧客に送信します

これがお役に立てば幸いです。これらはナノサービスではなくマイクロサービスであることを忘れないでください。同じ問題ドメインを分割しようとしないでください。したがって、質問のタイトルに答えるために、マイクロサービスを適切なサイズに保つと、その問題ドメインのビジネスロジックのすべて、またはほとんどが、そのマイクロサービス内に存在できます。

12
TheCatWhisperer

それはすべてあなたの正確な要件に依存します。

予約を行う2つのアプリケーションがあるとします。

  1. 最初のケース:1つのアプリケーションで1人のユーザーが複数回予約できるようにし、もう1つのアプリケーションでは1人しか許可しない場合があります。これは、予約の制限がアプリケーションレベルにあることを意味します。たとえば、予約システムに2つのエントリポイントがある(マルチ予約を許可するものと許可しないものがある)、または関連するマイクロサービスでそれをチェックするだけです。応用。
  2. 2番目のケース:アプリケーションが何であれ、ユーザーが複数のものを持つことができないのは「予約」の定義の一部であり、このルールはシステム全体に当てはまります。つまり、予約マイクロサービスにチェックを入れることができます。

通知システムについては、新しい予約をリッスンするために、マイクロサービスに予約サービスをサブスクライブさせることができます。そのため、予約マイクロサービスはすべての加入者に通知し、それに応じて行動します。

この種類のアーキテクチャの唯一の問題は、通知が公開された後に何かが失敗した場合にどうなるかです。2つのマイクロサービスは、同じデータベーストランザクションで実行される2つの関数のように機能しないため、エラーを適切に処理し、最終的にプロセスを再生する必要があります。失敗した(自動または手動)

1
Walfrat

簡単な答えは、マイクロサービスのクライアントが「純粋な」マイクロサービスアーキテクチャでビジネスロジックを管理することです。理解を容易にするために、さらに単純な例を検討してください。 URIに基づいてバイトのストリームを返すだけのサービス。それ自体は、それほど有用ではありません。どのURIに何が含まれているかを何らかの方法で把握していなければ、どこからプルするかを推測することしかできません。次に、検索機能を提供する別のマイクロサービスがあるとします。クエリ文字列を含むリクエストを送信すると、URIが返されます。今、物事はより面白くなります。最初のサービスのURIへの参照をインデックスに入れることができます。

しかし、それでも、これらの2つを何らかの形で調整する必要があります。答えは簡単です。ブラウザを使用してインデックスサービスからURIを取得し、データサービスからデータを取得します。どちらのサービスも他のサービスを「認識」しておらず、それらの間には絶対的な結合はありません。他のデータサービスでインデックスサービスを使用でき、その逆も可能です。

これがすべてのシナリオで最良のアプローチであるとは限りませんが、この方法で物事を構築することには多くの利点があり、特に現在知られていないシナリオでの再利用性があります。

0
JimmyJames