私はモノリシックなアプローチに慣れているので、マイクロサービスアーキテクチャに頭を抱えようとしています。
非常に簡略化された Uber予約システムを構築しようとしているとします。物事を簡単にするために、クライアントに3つのサービスとゲートウェイAPI Booking
、Drivers
、Notification
があり、次のワークフローがあるとします。
新しい予約を作成する場合:
すべてのメッセージングが、kafkaなどのメッセージングバスではなく、http呼び出しを介して行われるとしましょう。
したがって、この場合、Booking
サービスが既存の予約のチェックを実行できると思いました。しかし、利用可能なドライバと通知のリストを誰が取得する必要がありますか?ゲートウェイレベルで実行することを考えていますが、ロジックは次の2つの場所に分割されています。
Gateway
-利用可能なドライバーのリストを取得+通知を送信Booking
-既存の予約を確認そして、ゲートウェイはそれを行うのに適切な場所ではないと確信していますが、Booking
サービスでそれを行っている場合、緊密に結合されているように感じますか?
さらに複雑にするために、予約システムを再利用したいが、独自のビジネスロジックを上に置いた別のプロジェクトがある場合はどうなりますか?新しいプロジェクトゲートウェイが独自のビジネスロジックを既存のものから分離できるように、ゲートウェイレベルでそれを行うことを考えたのはそのためです。
それを行う別の方法は、各プロジェクトがコア予約サービスと通信する独自の予約サービスを持っていることですが、ここでの最善のアプローチは何なのかわかりません:-)
人々はしばしば「マイクロサービス」を聞いて「ナノサービス」を考えます、そしてこれはいくつかの混乱を引き起こす可能性があります。これらはmicro-servicesなので、エンティティごとに個別のサービスを用意する必要はありません。あなたがしようとしているすべてがbooking
とnotification
サービスにあるはずです。 driver
サービスは必要ありません(説明したアクティビティの場合)。
bookで利用可能なドライバのリストを取得することは、booking
サービスに該当します。一般的な落とし穴は、関連するアクティビティを同じサービスにグループ化しないことです。これは低コヒーレンスと呼ばれ、非常に悪いです。エンティティごとではなく、問題ドメインごとに物事をサービスにグループ化することを忘れないでください。
さて、再利用に関しては、個別のマイクロサービスを持つことの利点は、消費者向けのアプリを作成する3つの個別のチームを持つことができるようになったことです。 Androidアプリとiosアプリです。これらすべての異なるアプリケーションは、まったく異なる方法で構築でき、特定のプラットフォームに適しているように見えます(コードを繰り返す必要はありません)。 booking
サービスコードは、これら3つのアプリすべてで再利用されます。これは、3つのアプリすべてが独自の予約コードを持たずにサービスにhttp呼び出しを行うためです。
一般的な予約フローは次のようになります。
booking
サービスを呼び出して、利用可能なドライバーのリストを取得しますbooking
サービスの「book」メソッドを呼び出しますbooking
サービスサービスは、予約の詳細でnotification
サービスを呼び出しますnotification
サービスはドライバーに通知を送信し、予約をドライバーに通知しますnotification
サービスにメッセージを送信しますnotification
サービスは、ドライバーがもうすぐそこにいるというアラートを顧客に送信しますこれがお役に立てば幸いです。これらはナノサービスではなくマイクロサービスであることを忘れないでください。同じ問題ドメインを分割しようとしないでください。したがって、質問のタイトルに答えるために、マイクロサービスを適切なサイズに保つと、その問題ドメインのビジネスロジックのすべて、またはほとんどが、そのマイクロサービス内に存在できます。
それはすべてあなたの正確な要件に依存します。
予約を行う2つのアプリケーションがあるとします。
通知システムについては、新しい予約をリッスンするために、マイクロサービスに予約サービスをサブスクライブさせることができます。そのため、予約マイクロサービスはすべての加入者に通知し、それに応じて行動します。
この種類のアーキテクチャの唯一の問題は、通知が公開された後に何かが失敗した場合にどうなるかです。2つのマイクロサービスは、同じデータベーストランザクションで実行される2つの関数のように機能しないため、エラーを適切に処理し、最終的にプロセスを再生する必要があります。失敗した(自動または手動)
簡単な答えは、マイクロサービスのクライアントが「純粋な」マイクロサービスアーキテクチャでビジネスロジックを管理することです。理解を容易にするために、さらに単純な例を検討してください。 URIに基づいてバイトのストリームを返すだけのサービス。それ自体は、それほど有用ではありません。どのURIに何が含まれているかを何らかの方法で把握していなければ、どこからプルするかを推測することしかできません。次に、検索機能を提供する別のマイクロサービスがあるとします。クエリ文字列を含むリクエストを送信すると、URIが返されます。今、物事はより面白くなります。最初のサービスのURIへの参照をインデックスに入れることができます。
しかし、それでも、これらの2つを何らかの形で調整する必要があります。答えは簡単です。ブラウザを使用してインデックスサービスからURIを取得し、データサービスからデータを取得します。どちらのサービスも他のサービスを「認識」しておらず、それらの間には絶対的な結合はありません。他のデータサービスでインデックスサービスを使用でき、その逆も可能です。
これがすべてのシナリオで最良のアプローチであるとは限りませんが、この方法で物事を構築することには多くの利点があり、特に現在知られていないシナリオでの再利用性があります。