web-dev-qa-db-ja.com

マイクロサービスは互いに対話する必要がありますか?

マイクロサービスを使用してアプリケーションを設計していますが、複数のサービスからデータを収集するために使用する最適なメカニズムがわかりません。

2つのオプションがあると思います。

  • サービスが直接通信できるようにする「サービス間」通信メカニズムを統合します。 API Gatewayは個別のサービスを呼び出し、次に他のサービスを呼び出してデータを収集してから、統合された応答をAPI Gatewayに返します。次に、APIは呼び出し元に応答を返します。 (これは、serviceBへの呼び出しがserviceAからの応答を必要とする場合、同期呼び出しでなければなりません。I.E個人と住所のサービスを分離します。)
  • API Gatewayで各サービスを直接呼び出し、応答を返す前にAPI内のデータを統合します。

サービスを相互に通信させるとカップリングが導入されるため、2番目のオプションに傾いています。この場合、モノリシックアプリケーションを設計するだけで十分です。ただし、このオプションを使用すると、頭から離れて考えることができるいくつかの重大な欠点があります。

  • APIに複数のサービスへの複数の呼び出しを実行させると、特に一部の呼び出しがブロックされている場合、APIサーバーの負荷が増加します。

  • この方法は、APIがアプリケーションが実行しようとしていることを「認識」している必要があることを意味します(IE Logicは、サービスの呼び出しを処理し、次にデータを統合するためにAPIにプログラムする必要があります)。マイクロサービスの愚かな「エンドポイント」として機能します。

この問題への標準的なアプローチが何であるか、そして私が見逃している別の3番目のオプションがあるかどうか知りたいのですが?

35
KidCode

マイクロサービスに相互に同期通信を行わせることはお勧めしません。大きな問題はカップリングです。つまり、サービスが相互にカップリングされ、2番目のサービスが失敗すると、2番目のサービスが完全にまたは部分的に機能しなくなります。

状態変更操作と読み取り操作を明確に区別します(CQS Command Query Separation )。状態変更操作の場合、私はある種のメッセージングインフラストラクチャを使用し、一気に忘れてしまいます。クエリの場合は、同期要求応答通信を使用し、http APIを使用するか、データストアに直接移動します。

メッセージングを使用している場合は、サービス間でイベントを発生させるためのパブリッシュサブスクライブを確認することもできます。

考慮すべきもう1つのポイントは、(トランザクションのみの)データ共有(読み取り専用ビューではなく)です。内部状態を公開すると、リーダーがデータの誤った状態またはバージョンを取得し、データがロックされる可能性がありますか?

最後に重要なことですが、サービスを自律的に(少なくとも論理レベルで)維持するためにできることはすべて実行してください。

これが理にかなっているといいのですが。

25
Sean Farmar

そのデータが必要な理由によって異なります。 UIの場合は、それで十分です。さらに、それは本来あるべき姿です。 Chris Richardsonが concept について素晴らしい説明をしており、Sam Newmanが Backends for Frontends と呼ばれる非常に類似した概念についての素晴らしい記事を持っています。

しかし、いくつかのロジックにそれが必要な場合、サービス境界が間違っている可能性があります。

常識が私たちに言ういくつかの特徴があります 私たちのサービスが持つべきです 。彼らです:

  1. 低カップリング。サービスAに変更を加えた場合、それらがサービスBに影響を与えないようにします。
  2. 凝集力が高い。一部の機能を実装する必要がある場合は、影響を受けるサービスの数を最小限に抑える必要があります。
  3. 高い自律性。一部のサービスが失敗した場合、システム全体を停止させたくないでしょう。
  4. 粒度を修正します。あなたの ネットワークはもっと複雑なもの と思っている以上に、サービスがおしゃべりになりすぎたくありません。
  5. サービスはイベントを介して通信する必要があります。保守性が低下するため、サービスがお互いを認識しないようにする必要があります。新しいサービスを追加する必要がある場合はどうなるか考えてください。
  6. 分散データ。サービスは情報の保存方法を共有すべきではありません。優れたオブジェクトのように、データではなく動作を公開します。
  7. オーケストレーションに対するサービスの振り付け。

これを達成するために、 サービスの境界をビジネス機能として扱います 。サービス境界を特定する正式なプロセスは次のようになります。

  1. 上位レベルの境界を特定します。私はそれらを、あなたの組織がそのビジネス目標を達成し、そのビジネス価値を得るために歩むべきステップであると考えたいです。 Porter's Value chain を見て、基本的な手順を理解することができます。
  2. 各サービス内で、より深く掘り下げます。子供の自己完結型ユニットを自分の責任で特定します。
  3. 彼らのコミュニケーション方法に注意してください。正しいサービスは、主にイベントを介して通信します。組織構造について考えてください。内部のコミュニケーションはかなり集中的ですが、通常、いくつかの外部イベントが公開されます。

このアプローチを適用する は、興味深いかもしれません。

13
Zapadlo

私はおそらく「APIゲートウェイ」ではないかもしれませんが、デフォルトで2番目のアプローチにも頼りますが、唯一のnewマイクロサービスを作成することは完全に合理的だと思います目的は、他のマイクロサービスへのリクエストを調整し、より高いレベルの形式でデータを表すことでした。マイクロサービスアーキテクチャでは、「ベース」のマイクロサービスが互いに直接通信することはできません。

これをもう少し主観的にしないために、あるサービスが別のサービスに依存しているとすると、最初のサービスが2番目のサービスからのデータまたはサービスを必要とする場合直接的または間接的。数学の用語では、この関係を preorder ではなく、 partial order にする必要があります。ダイアグラム形式で、依存関係ダイアグラムをプロットした場合は、 ハッセダイアグラム が得られ、(有向)サイクルがないはずです。 (ハッセ図では、エッジは暗黙的に下から上に向けられます。)さらにガイドラインとして、上から下へのパスを一般的に短くする必要があります。これは、デフォルトで物事に直接依存することを意味します。その理由は、これにより特定のリクエストで問題が発生する可能性のあるものの数が最小限に抑えられ、オーバーヘッドが最小限に抑えられ、複雑さが軽減されるためです。したがって、この測定基準による「理想的な」ケースでは、ハッセ図には2つのレベルしかありません。もちろん、キャッシング、統合、ロードバランシング、障害管理などの中間サービスを導入したい理由はたくさんあります。

API Gatewayが「スマート」であるという2番目の懸念について詳しく説明するために、 Falcorのようなフレームワークで現在注目を集めているパターン/ Relay / GraphQL は、「API Gateway」が何を知らなくてもそれらの仕様を一般的に実行できるように、何をすべきかについてより多くの仕様を要求することですGetTimelineが必要です。代わりに、「ユーザーサービスからこのユーザー情報を要求し、ポストサービスからこれらの投稿を取得する」などの要求を取得します。

相互に「呼び出す」ためのサービスの必要性は、マイクロサービスが相互に「呼び出す」ための必要性が、マイクロサービスは適切に設計されています。

解決しようとしている問題について詳しく説明できますか?簡単な英語で?

0
Ben