gRPC の動機と設計原則
動機
Google では、10年以上にわたり、Stubby という単一の汎用 RPC インフラストラクチャを使用して、データセンター内外で実行されている多数のマイクロサービスを接続してきました。当社の内部システムは、今日人気を得ているマイクロサービスアーキテクチャを長年採用しています。均一でクロスプラットフォームな RPC インフラストラクチャを持つことで、この期間の信じられないほどの成長をサポートするために不可欠な、効率、セキュリティ、信頼性、および動作分析におけるフリート規模の改善をロールアウトすることができました。
Stubby には多くの優れた機能がありますが、標準に基づいているわけではなく、内部インフラストラクチャに tightly coupled すぎるため、公開リリースには適しているとは言えません。SPDY、HTTP/2、QUIC の登場により、これらの機能の多くが公開標準に登場し、Stubby が提供しないその他の機能も追加されました。この標準化を活用し、モバイル、IoT、および Cloud のユースケースへの適用範囲を拡大するために、Stubby を再構築する時期が来たことは明らかでした。
原則と要件
オブジェクトではなくサービス、参照ではなくメッセージ
システム間の粗粒度のメッセージ交換というマイクロサービス設計哲学を推進し、分散オブジェクトの落とし穴 や ネットワークを無視する誤謬 を回避します。
カバレッジとシンプルさ
スタックは、すべての人気のある開発プラットフォームで利用可能であり、選択したプラットフォームで簡単に構築できるようにする必要があります。CPU およびメモリが制限されたデバイスでも実行可能である必要があります。
無料とオープン
基本的な機能はすべての人に無料で利用できるようにします。すべての成果物を、採用を促進し、妨げないライセンスを持つオープンソースの取り組みとしてリリースします。
相互運用性とリーチ
ワイヤプロトコルは、一般的なインターネットインフラストラクチャを横断して生存できる能力が必要です。
汎用性とパフォーマンス
スタックは、ユースケース固有のスタックと比較してパフォーマンスをほとんど犠牲にすることなく、幅広いユースケースに適用できる必要があります。
レイヤード
スタックの主要な側面は、独立して進化できるようにする必要があります。ワイヤフォーマットの改訂は、アプリケーションレイヤーのバインディングを中断してはなりません。
ペイロード非依存
異なるサービスでは、プロトコルバッファ、JSON、XML、Thrift などの異なるメッセージタイプとエンコーディングを使用する必要があります。プロトコルと実装はこれを可能にする必要があります。同様に、ペイロード圧縮の必要性はユースケースとペイロードタイプによって異なります。プロトコルは、プラグ可能な圧縮メカニズムを許可する必要があります。
ストリーミング
ストレージシステムは、大規模なデータセットを表現するためにストリーミングとフロー制御に依存しています。音声認識からテキストへの変換や株価ティッカーなどの他のサービスは、時間的に関連するメッセージシーケンスを表現するためにストリーミングに依存しています。
ブロッキングとノンブロッキング
クライアントとサーバー間で交換されるメッセージシーケンスの非同期および同期処理の両方をサポートします。これは、特定のプラットフォームでのスケーリングとストリームの処理に不可欠です。
キャンセルとタイムアウト
操作は高価で長期間にわたる可能性があります。キャンセルにより、クライアントが正常に動作している場合、サーバーはリソースを回復できます。作業の因果チェーンが追跡されると、キャンセルは連鎖する可能性があります。クライアントは呼び出しのタイムアウトを示すことができ、これによりサービスはクライアントのニーズに合わせて動作を調整できます。
レイムダッキング
サーバーは、インフライトの処理を継続しながら、新しいリクエストを拒否することで、正常にシャットダウンできる必要があります。
フロー制御
クライアントとサーバーの間では、コンピューティングパワーとネットワーク容量がしばしば不均衡です。フロー制御により、バッファ管理が改善され、過剰にアクティブなピアからの DOS に対する保護も提供されます。
プラグ可能
ワイヤプロトコルは、機能する API インフラストラクチャの一部にすぎません。大規模な分散システムには、セキュリティ、ヘルスチェック、ロードバランシングとフェイルオーバー、監視、トレース、ロギングなどが不可欠です。実装は、これらの機能をプラグインするための拡張ポイントを提供し、有用な場合はデフォルトの実装を提供する必要があります。
APIとしての拡張機能
サービス間のコラボレーションを必要とする拡張機能は、可能な限りプロトコル拡張機能ではなく API を使用することを優先する必要があります。このタイプの拡張機能には、ヘルスチェック、サービスイントロスペクション、ロード監視、ロードバランシング割り当てなどが含まれます。
メタデータ交換
認証やトレースなどの共通のクロスサービング関心事は、サービスで宣言されたインターフェースの一部ではないデータの交換に依存します。デプロイメントは、サービスが公開する個々の API とは異なる速度でこれらの機能を進化させる能力に依存します。
標準化されたステータスコード
クライアントは通常、API 呼び出しから返されたエラーに対して限られた数の方法で応答します。ステータスコード名前空間を制限して、これらのエラー処理決定を明確にする必要があります。よりリッチなドメイン固有のステータスが必要な場合は、メタデータ交換メカニズムを使用して提供できます。