マイクロサービス間でDTOを共有する方法は?


33

私のシナリオは次のとおりです。

さまざまな種類のセンサーからデータを受信し、後でさまざまなフロントエンドおよび分析サービスで使用できるように変換して保持するように設計されたシステムを設計しています。

私はすべてのサービスを可能な限り独立したものにしようとしていますが、問題があります。チームは、使用したいDTOを決定しました。外向きサービス(センサーデータ受信者)は、独自の方法でデータを受信し、JSONオブジェクト(DTO)に変換して、メッセージブローカーに送信します。メッセージのコンシューマーは、センサーデータメッセージの読み取り方法を正確に知ることができます。

問題は、いくつかの異なるサービスで同じDTOを使用していることです。更新プログラムは複数の場所に実装する必要があります。明らかに、ここでDTOのいくつかの余分なフィールドや不足しているフィールドを設計しました。サービスが更新されるまで問題はあまりありませんが、それでも私を悩ませ、気分が良くなります。間違いを犯す。簡単に頭痛になります。

システムを間違って設計しようとしていますか?そうでない場合、これを回避する方法は何ですか、または少なくとも私の心配を緩和するために?


共有しているDTOの種類と、サービス間で使用しているプロトコルは何ですか?たとえば、protogRPC のファイルまたはavroKafka のスキーマを共有し、両方のサービスでDTOを生成してもかまいませんが、2つのプロジェクト間で共有ライブラリを共有することはありません。
ビンセントサ

エンコードされたJSON文字列とAMQP。言語固有のものを使用しないことを希望します。
nbaughman

回答:


38

私のアドバイスは?これらのDTOは、あらゆる種類のライブラリのアプリケーション間で共有しないでください。または、少なくとも今はこれをしないでください。

直観に反しているようです。コードを複製していますか?ただし、これはビジネスルールではないため、より柔軟に対応できます。

DTOを送信するサービスは、Rest APIのように、メッセージコントラクトで厳格である必要があります。サービスは、DTOからの情報を既に使用している他のサービスを破壊するような方法でDTOを変更できません。

新しいフィールドがDTOん追加された場合、あなただけのこのDTOを消費する他のサービスを更新した場合、彼らは新しいフィールドを必要としています。そうでなければ、忘れてください。JSONをコンテンツタイプとして使用すると、DTOの実際のバージョンでこれらの新しいフィールドをマップしないサービスのコードを壊すことなく、新しい属性を作成して送信する柔軟性があります。

しかし、もしこの状況が本当にあなたを悩ませているなら、3つルールに従うことができます:

再利用には2つの「3つのルール」があります。(a)再利用可能なコンポーネントを使い捨てコンポーネントとして構築するのは3倍困難です。(b)再利用可能なコンポーネントは、再利用ライブラリに受け入れます。

そのため、サービス間でこのDTOを共有する前にもう少し待つようにしてください。


1
非常に高く評価。これは、私が今後進めている数少ない大きな懸念事項の1つです。夜に私を維持するのに十分ではありませんが、私を心配するのに十分です。
nbaughman

4
(異なる独立したサービスの)複製されたDTOは、DRYに違反しません。それでおしまい。
ライヴ

3
おそらく、1回限りの操作として、あるプロジェクトから別のプロジェクトにDTOソースコードを直接コピーしない理由はありませんが、新しいプロジェクトで不要な部分はおそらく削除する必要があります。
bdsl

1
サービス全体が削除されても、システム全体に大きな問題は生じません。理想的には。
ライヴ

4
答えの本質を明確にするために、マイクロサービスを開発するとき、各サービスは、必要な実際の契約を除き、他のサービスについて知らないかのように開発する必要があります。
ジョナサン

12

マイクロサービスに関しては、サービスの開発ライフサイクルも独立している必要があります。*

異なるSLDCと異なる開発チーム

実際のMSシステムでは、エコシステムの開発に関与する複数のチームが存在し、各チームが1つ以上のサービスを担当しています。順番に、これらのチームは異なるオフィス、都市、国、計画に配置される可能性があります...おそらく、彼らはお互いのことさえ知らないので、知識やコードを共有することを非常に難しくしています(可能であれば)。しかし、これは非常に便利です。なぜなら、共有コードは一種の共有の推論を暗示し、特定のチームにとって意味のあるものは別のチームのために作る必要がないということを思い出すことが重要だからです。たとえば、DTO Customerを指定すると、プレイ中のサービスによって異なる場合があります。これは、顧客が各サービスとは異なる方法で解釈(または表示)されるためです。

さまざまなニーズ、さまざまなテクノロジー

また、分離されたSLDCにより、チームはニーズに最適なスタックを選択できます。特定のテクノロジーで実装されたDTOを課すと、チームが選択する能力が制限されます。

DTOはビジネスルールでもサービス契約でもありません

DTOは本当に何ですか?データを一方から他方に移動する以外の目的のないプレーンオブジェクト。ゲッターとセッターのバッグ。まったく知識がないため、全体として再利用する価値のある種類の「知識」ではありません。また、不安定なため、カップリングの候補としても不適切です。

Dherikが述べたことに反して、サービスは、他のサービスを同時に変更する必要なく、DTOを変更できる必要あります。サービス寛容な読者、寛容な作家、失敗に寛容でなければなりません。それ以外の場合は、サービスアーキテクチャが意味をなさないような方法で結合を引き起こします。Dherikの答えとは逆に、3つのサービスがまったく同じDTOを必要とする場合、サービスの分解中に何かがうまくいかなかった可能性があります。

異なるビジネス、異なる解釈

サービス間に横断的な概念が存在する可能性がありますが、すべてのサービスがそれらを同じ方法で解釈することを強制する標準モデルを課す必要があるわけではありません。

ケーススタディ

弊社には、カスタマーサービス販売配送の 3つの部門があるとします。これらのそれぞれが1つ以上のサービスをリリースするとします。

顧客サービスは、そのドメイン言語のために、顧客である顧客の概念を中心にサービスを実装します。たとえば、顧客は、名前年齢性別電子メール電話などとしてモデル化されます

さて、Sales and Shippingはそれぞれのドメイン言語に従ってサービスをモデル化します。これらの言語では、概念顧客も表示されますが、微妙な違いがあります。彼らにとって、顧客 は(必ずしも)人ではありません。以下のために 販売、顧客がある文書番号クレジットカード請求先住所のため、出荷フルネーム配送先住所を過ぎます。

私たちが強制した場合の販売および出荷をの標準的なデータモデルを採用する顧客サービスを、我々は、彼らが全体の表現を維持し続けなければならない場合には不必要な複雑さを導入してしまう可能性があり、不必要なデータを扱うためにそれらを強制している顧客と同期してデータを顧客サービス

関連リンク


*ここに、このアーキテクチャの長所があります


ありがとうございました!実際、ケーススタディは、DTOを共有するかどうかを判断するのに役立ちました。今、私はそれらを共有したくない理由について確信しています。
イゴール

8

私はすべてのサービスを可能な限り独立するように設計しようとしています

イベントを公開する必要があります。イベントは、特定の時点で発生した何かについての確かな事実を表す特定のタイプのメッセージです。

各サービスには非常に明確に定義された責任があり、その責任に関連するイベントを公開する責任があります。

さらに、イベントは技術的なイベントではなく、ビジネス関連のイベントを表すようにします。たとえばOrderCancelledOrderUpdatedwith よりイベントを優先しstatus: "CANCELLED"ます。

このようにして、サービスがキャンセルされた注文に対応する必要がある場合、そのイベントに関連するデータのみを運ぶ特定のタイプのメッセージをリッスンするだけで済みます。たとえば、OrderCancelledおそらくちょうど必要order_idです。これに対応する必要のあるサービスは、それ自体のデータストアに注文について知る必要があるものをすでに保存しています。

しかし、サービスOrderUpdatedがリッスンするイベントのみを持っている場合、イベントのフローを解釈する必要があり、注文がキャンセルされたときに正しく終了するように配信順序に依存するようになりました。

あなたは、センサデータを公開しているとして、あなたのケースでは、しかし、それがサービスを持っていることに意味を作ることができ、イベントに耳を傾け、例えば「ビジネスイベント」の新しいストリームを公開しTemperatureThresholdExceededTemperatureStabilised

また、作成するマイクロサービスが多すぎることに注意してください。マイクロサービスは複雑さをカプセル化する優れた方法ですが、適切なサービスの境界を見つけられない場合は、サービス統合が複雑になります。そして、それは維持する悪夢です。

サービスが少なすぎ、大きすぎる場合は、サービスが多すぎ、小さすぎる場合よりも優れています。


私は間違いなく同意します。センサーデータは、メッセージを解析してブローカーに発行する前に組織全体で合意された形式に変換するマイクロサービスに直接送られます。メッセージを読み取ってデータベースに保持するサービスと、メッセージの分析を実行して独自の処理を実行するサービスがあります。各サービスは、ビジネスの性質上、行うべきことはあまりないため、(できれば)非常にシンプルなサービスにつながります。
-nbaughman

2
@ Nickdb93-センサーデータを公開している場合、サービスを持ち、イベントをリッスンし、TemperatureThresholdExceeded、TemperatureStabilisedなどの「ビジネスイベント」の新しいストリームを公開することは理にかなっています。(回答に追加)
ピート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.