コアコンセプト、アーキテクチャ、ライフサイクル
gRPCの主要なコンセプトの紹介と、gRPCアーキテクチャおよびRPCライフサイクルの概要。
コアコンセプト、アーキテクチャ、ライフサイクル
gRPCに慣れていない場合は、まずgRPCの概要をお読みください。言語固有の詳細については、お好みの言語のクイックスタート、チュートリアル、およびリファレンスドキュメントを参照してください。
概要
サービス定義
多くのRPCシステムと同様に、gRPCはサービスを定義し、パラメータと戻り値の型を使用してリモートで呼び出すことができるメソッドを指定するという考えに基づいています。デフォルトでは、gRPCはサービスインターフェイスとペイロードメッセージの構造の両方を記述するためのインターフェース定義言語(IDL)としてプロトコルバッファを使用します。必要に応じて、他の代替手段を使用することも可能です。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
gRPCでは、4種類のサービスメソッドを定義できます。
クライアントがサーバーに単一のリクエストを送信し、通常の関数呼び出しのように単一のレスポンスを返す単項RPC。
rpc SayHello(HelloRequest) returns (HelloResponse);
クライアントがサーバーにリクエストを送信し、メッセージのシーケンスを読み取るためのストリームを取得するサーバー ストリーミングRPC。クライアントはメッセージがなくなるまで返されたストリームから読み取ります。 gRPCは、個々のRPC呼び出し内でのメッセージの順序を保証します。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
クライアントがメッセージのシーケンスを書き込み、提供されたストリームを使用してサーバーに送信するクライアント ストリーミングRPC。クライアントはメッセージの書き込みが完了すると、サーバーがそれらを読み取ってレスポンスを返すのを待ちます。ここでも、gRPCは個々のRPC呼び出し内でのメッセージの順序を保証します。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
両側が読み書きストリームを使用してメッセージのシーケンスを送信する双方向ストリーミングRPC。 2つのストリームは独立して動作するため、クライアントとサーバーは任意の順序で読み書きできます。たとえば、サーバーはすべてのクライアントメッセージを受信するまで応答を書き込むのを待つことも、メッセージを読み取ってからメッセージを書き込むことを交互に行うことも、その他に読み書きの組み合わせをすることもできます。各ストリーム内のメッセージの順序は保持されます。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
さまざまな種類のRPCの詳細については、以下のRPCライフサイクルセクションで学習します。
APIの使用
.proto
ファイル内のサービス定義から始めて、gRPCはクライアント側およびサーバー側のコードを生成するプロトコルバッファコンパイラプラグインを提供します。 gRPCユーザーは通常、クライアント側でこれらのAPIを呼び出し、サーバー側で対応するAPIを実装します。
- サーバー側では、サーバーはサービスによって宣言されたメソッドを実装し、クライアントコールを処理するgRPCサーバーを実行します。 gRPCインフラストラクチャは、受信リクエストをデコードし、サービスメソッドを実行し、サービスレスポンスをエンコードします。
- クライアント側では、クライアントには、サービスと同じメソッドを実装する*スタブ*(一部の言語では、優先される用語は*クライアント*)と呼ばれるローカルオブジェクトがあります。クライアントは、ローカルオブジェクトでそれらのメソッドを呼び出すだけで済み、メソッドは呼び出しのパラメータを適切なプロトコルバッファメッセージタイプにラップし、リクエストをサーバーに送信し、サーバーのプロトコルバッファ応答を返します。
同期と非同期
サーバーからの応答が到着するまでブロックする同期RPC呼び出しは、RPCが目指す手続き呼び出しの抽象化に最も近い近似です。一方、ネットワークは本質的に非同期であり、多くの場合、現在のスレッドをブロックせずにRPCを開始できると便利です。
ほとんどの言語のgRPCプログラミングAPIには、同期と非同期の両方のフレーバーがあります。各言語のチュートリアルとリファレンスドキュメント(完全なリファレンスドキュメントは近日公開予定)で詳細を確認できます。
RPCライフサイクル
このセクションでは、gRPCクライアントがgRPCサーバーメソッドを呼び出したときに何が起こるかについて詳しく見ていきます。完全な実装の詳細については、言語固有のページを参照してください。
単項RPC
まず、クライアントが単一のリクエストを送信し、単一のレスポンスを取得する最も単純なタイプのRPCを検討します。
- クライアントがスタブメソッドを呼び出すと、サーバーには、この呼び出しのクライアントのメタデータ、メソッド名、および指定されたデッドライン(該当する場合)でRPCが呼び出されたことが通知されます。
- サーバーは、自身の初期メタデータ(応答の前に送信する必要があります)をすぐに返信するか、クライアントのリクエストメッセージを待機することができます。どちらが最初に発生するかは、アプリケーション固有です。
- サーバーにクライアントのリクエストメッセージがあると、応答を作成して設定するために必要な作業を行います。応答は、ステータス詳細(ステータスコードとオプションのステータスメッセージ)およびオプションのトレーリングメタデータとともに、クライアントに(成功した場合)返されます。
- 応答ステータスがOKの場合、クライアントは応答を取得し、クライアント側の呼び出しが完了します。
サーバー ストリーミングRPC
サーバー ストリーミングRPCは、サーバーがクライアントのリクエストに応じてメッセージのストリームを返す点を除いて、単項RPCに似ています。すべてのメッセージを送信した後、サーバーのステータス詳細(ステータスコードとオプションのステータスメッセージ)およびオプションのトレーリングメタデータがクライアントに送信されます。これにより、サーバー側の処理が完了します。クライアントは、サーバーのメッセージをすべて受信すると完了します。
クライアント ストリーミングRPC
クライアント ストリーミングRPCは、クライアントが単一のメッセージではなくメッセージのストリームをサーバーに送信する点を除いて、単項RPCに似ています。サーバーは、通常はすべてのクライアントメッセージを受信した後ですが、必ずしもそうとは限りませんが、単一のメッセージ(ステータスの詳細とオプションのトレーリングメタデータとともに)で応答します。
双方向ストリーミングRPC
双方向ストリーミングRPCでは、呼び出しは、クライアントがメソッドを呼び出し、サーバーがクライアントのメタデータ、メソッド名、およびデッドラインを受信することによって開始されます。サーバーは、初期メタデータを返すか、クライアントがメッセージのストリーミングを開始するのを待つかを選択できます。
クライアント側およびサーバー側のストリーム処理はアプリケーション固有です。 2つのストリームは独立しているため、クライアントとサーバーは任意の順序でメッセージを読み書きできます。たとえば、サーバーはすべてのクライアントのメッセージを受信するまでメッセージを書き込むのを待つことができます。また、サーバーとクライアントは「ピンポン」を行うことができます。サーバーはリクエストを取得し、応答を返し、クライアントは応答に基づいて別のリクエストを送信します。など。
デッドライン/タイムアウト
gRPCを使用すると、クライアントは、RPCがDEADLINE_EXCEEDED
エラーで終了するまでにRPCが完了するのをどれだけ待つかを指定できます。サーバー側では、サーバーは特定のRPCがタイムアウトしたかどうか、またはRPCを完了するまでに残された時間をクエリできます。
デッドラインまたはタイムアウトの指定は言語固有です。一部の言語APIはタイムアウト(時間の間隔)の観点で機能し、一部の言語APIはデッドライン(時間の固定点)の観点で機能し、デフォルトのデッドラインがある場合とない場合があります。
RPCの終了
gRPCでは、クライアントとサーバーの両方が呼び出しの成功について独立してローカルな決定を下し、その結論が一致しない場合があります。これは、たとえば、サーバー側で正常に終了したRPC(「すべての応答を送信しました!」)があるが、クライアント側では失敗する(「応答がデッドライン後に到着しました!」)可能性があることを意味します。サーバーが、クライアントがすべてのリクエストを送信する前に完了することを決定することも可能です。
RPCのキャンセル
クライアントまたはサーバーのいずれかは、いつでもRPCをキャンセルできます。キャンセルはRPCをすぐに終了するため、それ以上の作業は行われません。
警告
キャンセル前に行われた変更はロールバックされません。メタデータ
メタデータは、キーが文字列であり、値が通常は文字列であるキーと値のペアのリストの形式の、特定のRPC呼び出しに関する情報(認証の詳細など)です。ただし、バイナリデータにすることもできます。
キーは大文字と小文字が区別されず、ASCII文字、数字、および特殊文字-
、_
、.
で構成され、grpc-
で始めることはできません(これはgRPC自体用に予約されています)。バイナリ値のキーは-bin
で終わり、ASCII値のキーは終わりません。
ユーザー定義のメタデータはgRPCでは使用されません。これにより、クライアントは呼び出しに関連付けられた情報をサーバーに提供でき、その逆も可能です。
メタデータへのアクセスは言語に依存します。
チャネル
gRPCチャネルは、指定されたホストとポート上のgRPCサーバーへの接続を提供します。これは、クライアントスタブを作成する際に使用されます。クライアントはチャネル引数を指定して、メッセージ圧縮のオン/オフ切り替えなど、gRPCのデフォルトの動作を変更できます。チャネルには、connected
やidle
などの状態があります。
gRPCがチャネルのクローズをどのように処理するかは、言語に依存します。一部の言語では、チャネルの状態を照会することもできます。