web-dev-qa-db-ja.com

パブリッシュ/サブスクライブパターンでメッセージスキーマに同意する方法

私はPubSub(GCP)を使用するプロジェクトに取り組んでいます。私の質問はGCPに固有ではありません。それはアーキテクチャパターンに関するものです(静的に型付けされた言語に慣れており、その方法を理解するのに苦労しています)これは正しい方法です)。

私が取り組んでいるサービスはgoで書かれており、私が望んでいることは(少なくとも私にとってはこれは正しい方法のようです)、コンシューマーとプロデューサーが同じメッセージ形式を使用するように強制することです(コンパイル時にスキーマに同意します)。 。現在、2つの部分は完全に独立しているので、メッセージ形式が2か所で指定されています(これは本当に私を悩ませます)。

最初は、消費者がメッセージ形式を所有するべきだと思いました(この種類のアーキテクチャに慣れていないと判断しないでください)、同僚と話し合い、後でいくつかの読書をしましたが、これはちょっと壊れることに同意しますパターンは、プロデューサーがコンシューマーについて知っているように、複数のコンシューマーがある場合にも問題が発生します。

次に考えたのは、メッセージフォーマットを別のパッケージに抽出し、そこからコンシューマーとプロデューサーの両方にフォーマットを使用させることでしたが、これでもカップリングが増加します。私はこれについていくつか読んでみましたが、私の質問に答えるパターンの詳細な説明/図を見つけることができません。この問題について考えたのは私だけではありません。

私は正しい軌道に乗っていますか、これを解決する正しい方法は何でしょうか?それとも私は私の人生を必要以上に複雑にしていますか?

1
alex

パブリッシャーとコンシューマーはすでに結合されています。つまり、スキーマを共有する結合の形式 外部結合 です。そのため、そのスキーマを定義するいくつかの一般的なモジュールを参照しても、実際には結合が増えるわけではなく、より明示的になるだけです。

特定の言語のカスタムソースコードから Yang のような言語に依存しない形式まで、さまざまなスキーマ形式があります。言語に依存しないものはより一般的ですが、使用するには何らかの翻訳またはコード生成手順が必要です。スキーマをソースコードとして定義すると、別のプログラミング言語を使用してメッセージを生成または消費する必要がない限り、より簡単に使用できます。

2
Karl Bielefeldt

およそ4つの異なる一般的なシナリオのクラスが表示されます(バイナリを実行しているインスタンスではなく、ソフトウェアパッケージについて話しています)。

  1. 単一のプロデューサー、単一のコンシューマー-この時点では、スキーマがどこに存在するかは(大いに)重要ではありませんが、存在するのは1つだけです。責任は「スキーマ所有者」にあり、「スキーマユーザー」がそれがどこにあるか、およびスキーマへのバージョン変更が発生したかどうか、いつ発生したかを確実に認識します。

  2. 単一のプロデューサー、複数のコンシューマー-この時点で、スキーマの最適な場所は間違いなくプロデューサー側です。

  3. 複数のプロデューサー、単一のコンシューマー-この時点で、スキーマはコンシューマー内に存在するのが1つしかないため、おそらくそれが最善です。

  4. 複数のプロデューサー、複数のコンシューマー-この時点では、専用の「スキーマリポジトリ」が間違いなく最良の選択です。

4のソリューションは1、2、3でも機能することに注意してください。これは、メッセージと、場合によってはコードの一般的な便利な関数を公開する「スキーマ」のGoモジュールを用意することで実現できます。

専用の「プロデューサーでもコンシューマーでもない」モジュールに配置することは、スキーマが変更されたときにバージョン管理を更新するだけでよく、プロデューサー/コンシューマーのバージョンバンプがフォーマットバンプでもあるかどうかを常に疑う必要がないことを意味します。

おそらく、(最も些細な場合以外は)プロデューサー側とコンシューマー側の両方で、関連する構造体型、マーシャリング、およびwhat-have-youを定義する必要はありません。

0
Vatine