gRPC とは
gRPC は、古くからあるリモート プロシージャ コール (RPC) プロトコルを進化させた最新のハイパフォーマンス フレームワークです。 アプリケーション レベルでは、gRPC により、クライアントとバックエンド サービス間のメッセージングが合理化されます。 Google から提供されている gRPC は、オープンソースであり、クラウドネイティブ オファリングの Cloud Native Computing Foundation (CNCF) エコシステムの一部です。 CNCF は、gRPC を Incubating (発展中) プロジェクトと見なしています。 Incubating とは、エンドユーザーが運用アプリケーションでそのテクノロジを使用しており、プロジェクトには多数の貢献者がいることを意味します。
一般的な gRPC クライアント アプリは、事業運営を実装するローカルのインプロセス関数を公開しています。 内部的には、そのローカル関数により、リモート マシン上の別の関数が呼び出されます。 ローカルの呼び出しのように見えますが、本質的には、リモート サービスへの透過的なアウトプロセス呼び出しです。 RPC のプラミングにより、コンピューター間のポイントツーポイント ネットワーク通信、シリアル化、および実行が抽象化されます。
クラウドネイティブ アプリケーションの場合、開発者は複数のプログラミング言語、フレームワーク、テクノロジにまたがって作業することがよくあります。 この "相互運用性" により、クロスプラットフォームの通信に必要なメッセージ コントラクトとプラミングが複雑になります。 gRPC には、このような懸案事項を抽象化する "均一な水平レイヤー" が用意されています。 開発者は、ビジネス機能に集中して、ネイティブ プラットフォームでコードを書き、通信のプラミングは gRPC で処理します。
gRPC は、Java、JavaScript、C#、Go、Swift、NodeJS など、ほとんどの一般的な開発スタックを包括的にサポートしています。
gRPC の利点
gRPC では、トランスポート プロトコルに HTTP/2 が使用され、多くの高度な機能が提供されます。
- データ転送のためのバイナリ フレーミング プロトコルです。テキストベースの HTTP 1.1 とは異なります。
- 同じ接続を介して複数の並列要求を送信するための多重化のサポート。HTTP 1.1 の場合、処理が一度に 1 つの要求および応答メッセージに制限されています。
- クライアント要求とサーバー応答の両方を同時に送信するための双方向全二重通信。
- 大規模なデータセットを非同期にストリーミングするための要求と応答を可能にする組み込みのストリーミング。
- ネットワークの使用量を減らすヘッダー圧縮。
gRPC は軽量でハイ パフォーマンスです。 メッセージが 60-80% 小さいので JSON シリアル化よりも最大 8 倍高速になる可能性があります。
プロトコル バッファー
gRPC はプロトコル バッファーというオープンソースのテクノロジを採用しています。 サービスが相互に送信する構造化メッセージをシリアル化するための、非常に効率的でプラットフォームに依存しないシリアル化形式が用意されています。 開発者は、クロスプラットフォームの インターフェイス定義言語 (IDL) を使用して、各マイクロサービスのサービスのサービス コントラクトを定義します。 コントラクトはテキストベースの .proto
ファイルとして実装され、各サービスのメソッド、入力、出力が記述されます。 同じコントラクト ファイルを、異なる開発プラットフォームで構築された gRPC クライアントやサービスに使用することができます。
proto ファイルを使用すると、Protobuf コンパイラ protoc
によってターゲット プラットフォーム用のクライアントとサービスの両方のコードが生成されます。 このコードには次のコンポーネントが含まれています。
- クライアントとサービスによって共有される厳密に型指定されたオブジェクト。メッセージのサービス操作とデータ要素を表します。
- リモート gRPC サービスによって継承および拡張できる、必要なネットワーク プラミングを備えた厳密に型指定された基底クラス。
- リモート gRPC サービスを呼び出すための必要なプラミングを含むクライアント スタブ。
実行時には、各メッセージは標準的な Protobuf 表現としてシリアル化され、クライアントとリモート サービスの間で交換されます。 JSON や XML とは異なり、Protobuf メッセージはコンパイルされたバイナリ バイトとしてシリアル化されます。
RPC ライフ サイクル
gRPC には、クライアントが gRPC サーバーと対話する方法として 4 つの rpc ライフ サイクルがあります。
単項 RPC
単項ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、応答が返されます。
クライアント ストリーミング RPC
クライアント ストリーミング ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、その後、サーバーから追加の応答を受けることなく、一連の追加のメッセージがクライアントからサーバーにストリーミングされます。
サーバー ストリーミング RPC
サーバー ストリーミング ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、その後、クライアントから追加の応答を受けることなく、一連のメッセージがサーバーからクライアントにストリーミングされます。
双方向ストリーミング RPC
双方向ストリーミング ライフ サイクルの場合、gRPC サーバーに対して要求が行われ、クライアントとサーバーの両方が相互に独立して動作しながら、一連のメッセージを送信します。
Application Gateway for Containers での gRPC の実装
Application Gateway for Containers には、単項、クライアント ストリーミング、サーバー ストリーミング、双方向ストリームという 4 つの各ライフ サイクルに従って要求をプロキシする機能があります。
gRPC 定義
構成は、Kubernetes Gateway API を使用して GRPCRoute リソースを定義することで実装されます (Application Gateway for Containers の Ingress API では gRPC はサポートされていません)。 各 GRPCRoute リソースは Gateway リソースを参照する必要があります。 要求を処理する規則が固有である場合、複数の GRPCRoute リソースが同じゲートウェイを参照することができます。
たとえば、次の GRPCRoute は Gateway-01
というゲートウェイにアタッチされます。
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-route-example
namespace: grpc-namespace
spec:
parentRefs:
- name: gateway-01
namespace: gateway-namespace
rules:
- matches:
- method:
service: ChatBotService
method: TalkBack
backendRefs:
- name: gRPC-TalkBack
port: 8080
注
gRPC は、Application Gateway for Containers に Gateway API を使用する場合にのみサポートされます。
正常性プローブ
Application Gateway for Containers の既定では、gRPC サービスを実行しているバックエンド ポートへの TCP ハンドシェイクを開始しようと試みます。 ハンドシェイクが完了すると、バックエンドは正常であると見なされます。
HealthCheckPolicy をカスタム正常性プローブとして使用する場合、定義されたポリシーによってプローブの動作が決まります。
gRPC バックエンドの HealthCheckPolicy の例を次に示します。
apiVersion: alb.networking.azure.io/v1
kind: HealthCheckPolicy
metadata:
name: gateway-health-check-policy
namespace: test-infra
spec:
targetRef:
group: ""
kind: Service
name: test-service
namespace: test-infra
default:
interval: 5s
timeout: 3s
healthyThreshold: 1
unhealthyThreshold: 1
port: 8123
grpc: {} # defined if probing a gRPC endpoint
UseTLS: true
この例では、protocol、port、UseTLS は省略可能ですが、サービスに複数のポッドが含まれており、gRPC ポッドが別のポートで公開されている場合は、そのポッドに対してプローブを明示的に開始する方法を参照できます。