1

分散環境 (「マイクロサービス」) で gRPC と共に Protobuf 3 を使用しています。

Protobuf 3 で設定されていない値または欠落している値をサポートしていないため、コントラクトの加算性に関連する次の問題が発生しました。

Service Aと、 Team BTeam Cが所有する2 つのコンシューマー サービスBCがあるとします。

フィールド、たとえばブール値をサービスAのコントラクトに追加すると、最初はデフォルト値があり、データベースにそのまま書き込まれます。

次に、チーム Bは更新されたコントラクトを使用して話すようにサービスを更新し、フィールド値として「true」を渡します。次に、チーム Cは引き続き古いコントラクトを使用し、同じサービスを呼び出します。値は false に置き換えられます。でもチームCはそんなつもりはなかったし、その分野のことを全く知らなかった。

したがって、サービス A は契約をまったく延長できません。さまざまな理由でまだ更新されていないコンシューマーはデータに損害を与える可能性があり、サービス A はそれに対して何もできないからです。

Thrift では、そのようなことは単一のチェック ( .isSet()) だけで行われます。

プリミティブをオブジェクトにラップするなどの汚い回避策がありますが、ライブラリ実装固有の参照によるチェック (少なくとも Java では) を使用する必要があります。また、最終的にはすべてをラッパーでラップする必要がありますが、ご想像のとおり、これも優れたソリューションではありません。

2017 年の Protobuf 3 でこのような状況を管理するために使用するベスト プラクティスは何ですか? チーム/サービス間の契約の更新をどのように管理/調整しますか? ありがとう

:この質問は、設定されていない/欠落している値の検出の欠如を実装する方法に関するものではなく、それをどのように処理し、 Protobuf 3 の哲学に従うかに関するものです。

4

2 に答える 2

2

ここでの問題は、この方法でフィールドの存在を確認しようとすることは、実際にはプロトコル バッファの慣用的な使用法ではないことだと思います (proto2 でさえ)。新しいフィールドを追加してスキーマを進化させようとしているようですが、更新されたクライアントからのものであることが確実でない限り、それらの新しいフィールドを読み取っていないようです。慣用的な方法は、代わりにこれを行うことです。新しいフィールドのデフォルトが適切であることを確認し、明示的に設定されていない場合でも互換性のある動作を維持するだけです。次に、存在をチェックしようとしないでください。フィールドを読むだけで、古いクライアントは適切なデフォルトの動作になります。

例として、有効または無効にできる新しい機能を追加するとします。これを行う正しい方法は、リクエスト メッセージに bool フィールドを追加することenable_new_featureです。古いクライアントはこのフィールドを知らないため、リクエストのデフォルトは false になり、期待どおりの古い動作が得られます。代わりにフィールドを追加するのdisable_new_featureはおそらく間違った方法です。そうすると、古いクライアントが望んでいないものを有効にすることで実際に壊れてしまうからです。

于 2016-12-08T17:13:46.803 に答える
1

Usingoneofは、ラッパーよりも優れた/よりクリーンな代替手段のように見えます。同様の質問に対するこの回答を参照してください: https://stackoverflow.com/a/40552570/618259

于 2016-12-07T18:37:18.037 に答える