私は最近マイクロサービスについてたくさん読んでいます、そしてここに私がこれまでに得た結論のいくつかがあります(私がどこかで間違っているなら私を訂正してください)。
このアーキテクチャについての私の理解を確認する以外に、質問の他の部分は主にサービスの発見に関連しています。サービスが非同期に通信していて、Amazon SQSのような中央のイベントキューを使用している場合、それはサービスディスカバリがそのようなアーキテクチャでその場所にないことを意味しますか?
サービスは、システム内の他のサービスに関する知識を持っていてはなりません。彼らが知っているのは、自分たちが公開またはサブスクライブする必要があるコンテキストとイベントだけです。
あなたの結論は主に確立されたようであり、マイクロサービスへの道を非常にうまくまとめています。
ただし、2、5、8は完全にはサポートしません。
2)単純な依存関係が自動的に合併につながるべきではありません。このような依存する呼び出しの頻度と、他のサービスからの呼び出しの頻度も考慮する必要があります。
したがって、マイクロサービスAがマイクロサービスBで非常に頻繁に機能を必要とし、マイクロサービスBが他のマイクロサービスでめったに必要とされない場合、想定される構造に挑戦し、両方のマイクロサービスをグループ化することが適切ではないかどうかを尋ねる必要があります。
5)もちろん、メッセージ処理で無限の循環を回避する必要があります。
しかし、仲介者を追加してもそれを防ぐことはできません。Aは、Cが処理するメッセージを起動し、Bが処理するメッセージを起動し、Aが処理するメッセージを起動し、ここでループに陥ります。
マイクロサービスレベルを検討するだけでは問題を評価できません。問題は、循環につながる可能性のあるメッセージのタイプとコンテンツに関するものです。したがって、サービス全体でのメッセージの分散と処理をモデル化するグラフを全体として分析する必要があります(実際、これは複雑になる可能性があるため、このようなサイクルを検出してそれらを破壊する監視マイクロサービスを想像できます)。
8)はい、各マイクロサービスには専用のストレージ/データベースが必要です。
サービスを独立させるには、最小限のレプリケーションが必要です。ただし、ここまではレプリケーションが望ましいとは言いません。レプリケーションプロセスによる隠されたカップリングを回避するために、レプリケーションは最小限に抑える必要があります。
マイクロサービスは疎結合に関するものです。これは、データを複製する代わりに、別のマイクロサービスを呼び出して関連データを取得することで、より効果的に実現できる場合があります。
最後の2つの番号なしの断言は、ここではしっかりと回答するには広すぎる。あなたの提案は良い出発点だと思いますが、それは実際にはアーキテクチャの要件と制約に依存しています。
マイクロサービスとは、さまざまな機能ドメインを分離することです。各サービスは、異なるテクノロジースタックを使用して、異なるチームが異なるペースで開発できます。これにより、組織の柔軟性が生まれます。トレードオフは運用の複雑さであり、追加のサービスごとに、運用環境で管理する必要があるもう1つのものが作成されます。したがって、モノリスとマイクロサービスの基本的なトレードオフは、依存関係を回避することではなく、すべてを一度に出荷する必要があるロックステップの開発とデプロイを回避することですが、より多くの可動部品。
サービスは、システム内の他のサービスに関する知識を持っていてはなりません。彼らが知っているのは、自分たちが公開またはサブスクライブする必要があるコンテキストとイベントだけです。
依存関係回避の問題は、赤ニシンです。製品の各部分の間には常に依存関係があり、それらが別のサービスにあるか同じコードの一部であるかに関係なく、依存関係が壊れる可能性があるという事実は変わりません。キーサーバーがダウンし、運用上の冗長性とフェイルオーバーの実践を通じてそれを管理するため、運用レベルで機能しなくなる可能性があります。また、パーツは互換性のない方法で変更されるため、統合テストで検出されるため、統合レベルで壊れることもあります。サービス間でコードをシャッフルしても、依存関係が壊れる可能性のある問題は解決されません。依存関係の破損を回避するためのソリューションは、運用の冗長性と統合テストであり、サービスのサイズとは関係ありません。
サービスが非同期に通信していて、Amazon SQSのような中央のイベントキューを使用している場合、それはサービスディスカバリがそのようなアーキテクチャでその場所にないことを意味しますか?
その質問に答えるために、最初にこれに答えてください:なぜ非同期で通信したいのですか?個別のコンポーネントの独立した開発を容易にするためですか? 24時間年中無休のシステムの運用の可用性を向上させるためですか?後者で、キューを使用してローカルデータベースにデータを複製するとします。さて、今あなたのデータは古くなっている可能性があります。いつかは古すぎるでしょう。どのように対処しますか?さらに、別のランタイムコンポーネントであるキューの運用可用性をどのように保証しますか?また、これらのローカルデータベースの可用性をどのように保証しますか? 1つのデータベースクラスターを管理する代わりに、いくつかのデータベースクラスターを使用できます。運用チームはこのワークロードを処理できますか?そして、本当に、単純なモノリスを構築した場合、ユーザーがより多くの機能と毎月数時間のダウンタイムでユーザーを満足させるかもしれないときに、その複雑さは価値がありますか?
私の言うとおりだと思います。システム設計は正しいか間違っているかではなく、多種多様なトレードオフから選択することです。あなたがそれを正しい文脈でしか見ないなら、間違っているすべてが正しい可能性があり、逆もまた同様です。あなたのコンテキストはあなたに固有なので、私たちはあなたにan答えを与えることができますが、それはthe答えにはなりません。あなたの聴衆が誰であるか、彼らのニーズは何か、そして適切なデザインがそれ自体を明らかにすることを覚えておいてください。
同意しない。 DDDは非常にオブジェクト指向になる傾向があります。注文は配信されましたか?マイクロサービスはDeliveryService.Deliver(order)を持つのに対し、Order.Deliver()
同意しない場合は、マイクロサービスをマイクロにしておく必要があります。さらに小さく分割してください!
同意しない。サービスは誰が呼び出しているかを気にする必要はなく、呼び出し元はロジックがマイクロサービスに実装されていることを気にすべきではありません。
キューは良いです。しかし、あなたの推論は間違っています。同期応答と非同期の唯一の違いは、同期応答を待つことです。 RPCスタイルの呼び出しをキューと複数のワーカーで実装することができます。
同意しない。マイクロサービスが結合されていないため、循環依存ではありません。また、SendEmail、EmailFailed、SendAgainには3つのマイクロサービスは必要ありません。
同意しない。 nano-servicesをチェックしてください。
同意しない。はい、分離されますが、マイクロサービスのオーケストレーションは、あらゆるモノリスプロジェクトと同じくらい困難な場合があります。
同意しない。ストレージを共有するべきではありませんが、マイクロサービスは可能な限りステートレスになるようにする必要があります。処理中でなければデータを複製しないでください
あなたの結論はいい経験則ですが、普遍的ではありません。グリーンフィールドプロジェクトであっても、これらのルールに違反することが最善のオプションである場合があります。場合によっては、同期通信が最適なオプションです。同期通信で結合されている場合でも、2つのサービスを1つにマージするのは適切でない場合があります。
そして、他の質問として、キューベースの通信にはサービス検出は必要ありません。
ええと、あなたはオブジェクト指向プログラミングについて話しているだけです。または、少なくとも、元々考えられていたもの:メッセージを使用して互いに通信する実行中の独立したコード。
OOPは、細胞が互いに比較的独立しており、他の細胞の外部インターフェイスに接続するメッセージを介して通信するだけである生物学的システムをモデルにしたものです。
では、なぜ、OOPと見なすのをやめるのですか?すべてのオブジェクトが同じコンピューター上で実行されていないからというだけですか?)どちらかと言えばさらにオブジェクト指向すべてのオブジェクトが同じアプリにある場合、開発者は多くの場合、OOPを壊すため、すべてのクラスで共有されているグローバル変数を使用し、各ファイルで同じヘッダーなど。すべてのオブジェクトが同じものに依存する場合、それらは互いに完全に独立している場合ほどカプセル化されず、カプセル化はOOPの全体のポイントです。
たとえば、他の回答で述べられているほぼすべては、OOPに関する教科書の声明です。
Bounded ContextやCore Domainのような重要な概念を誤って理解することがよくあるので、少し詳しく説明します。
サブドメインをビジネス機能として考えることは非常に有益であることがわかりました。ビジネス能力は、組織が行うことです。それはそのビジネス機能の1つです。私たちの目標は ビジネスとITの整合性 なので、私は彼らに 私の技術サービスと1対1の関係 を持たせたいと思います。
したがって、このプロセスは次のようになります。まず、より高いレベルのビジネス機能を定義します。名詞と動詞の形(またはいくつかの派生形)を取る必要があります。通常、ビジネス能力は10未満です。次に、ネストされた機能を識別して、非常に深くします。など、分割するものがなくなるまで。このアプローチを使用して実現した機能は、実際のドメイン、組織の実際の動作を反映しています。これらの機能は本質的に疎結合であるため、テクニカルサービスをこの機能にマップすると、自律的でイベント駆動型になります。このプロセスは ビジネス機能マッピング と呼ばれますが、サービスを見つける方法は他にもありますが、最も目立つのはおそらく バリューチェーン分析 です。
ここに例があります このアプローチを使用してサービス境界を識別する方法。