#このページで確認できること
- gRPC の1回のRPCが HTTP/2 の1ストリームにどうマッピングされるかを確認する
- grpcurl で unary RPC を呼び、headers / contents / trailers の3点を確認する
- 「HTTP 200 なのに
grpc-statusはエラー」という gRPC 特有の見え方を理解する - 観察するヘッダー:
content-type: application/grpc、te: trailers、trailers のgrpc-status/grpc-message
公開範囲: このサイトはgRPCサーバーを提供していません。このページのコマンドは、自分で管理する接続先に置き換えて使います。
#HTTP/2 へのマッピング
gRPC の1回のRPCは、HTTP/2 の1ストリームに対応します。ワイヤ上は次のようなHTTPメッセージです。
request — HTTP/2疑似ヘッダーの例:method: POST
:scheme: https
:path: /example.EchoService/Echo
:authority: grpc.example.com
content-type: application/grpc
te: trailers
grpc-timeout: 5S
DATA: [compressed-flag(1B)][length(4B)][protobuf message]
response — 結果は trailers で返る
:status: 200
content-type: application/grpc
DATA: [compressed-flag][length][protobuf message]
--- trailers ---
grpc-status: 0
grpc-message:
- 正常に成立したgRPC応答はHTTP 200: RPCの成否はtrailersの
grpc-statusで判断する(0 = OK, 5 = NOT_FOUND, 14 = UNAVAILABLE など)。トランスポート障害や非gRPC応答ではHTTP 200以外になることもある。 te: trailers: HTTP/2経路がtrailersを扱えることを確認するためのシグナル。標準gRPCに必要なtrailersが変換・欠落する経路では、RPCステータスを正しく伝えられない。- メッセージフレーミング: HTTP/2 DATAのペイロード上に「圧縮フラグ1バイト + 長さ4バイト + メッセージ本体」の列が流れる。gRPCメッセージ境界とDATAフレーム境界は一致せず、1メッセージが複数DATAにまたがる場合もある。
#4つのRPC形式
participants: Client, Server Client -> Server: HEADERS (:path /lab.EchoService/Echo) Client -> Server: DATA (request message) + END_STREAM Server --> Client: HEADERS (:status 200) Server --> Client: DATA (response message) Server --> Client: HEADERS (trailers: grpc-status 0) + END_STREAM
participants: Client, Server Client -> Server: HEADERS + DATA (request) + END_STREAM Server --> Client: DATA (message 1) Server --> Client: DATA (message 2) Server --> Client: DATA (message 3) Server --> Client: trailers (grpc-status 0) + END_STREAM
| 形式 | クライアント→ | →サーバー | 用途例 |
|---|---|---|---|
| unary | 1メッセージ | 1メッセージ | 通常のAPI呼び出し |
| server streaming | 1メッセージ | 複数メッセージ | ログ購読、フィード配信 |
| client streaming | 複数メッセージ | 1メッセージ | ファイルアップロード、メトリクス送信 |
| bidirectional | 複数メッセージ | 複数メッセージ | チャット、リアルタイム同期 |
#grpcurl での観測
grpcurlは、gRPCサービスをコマンドラインから確認するツールです。server reflectionが有効なら、サービス一覧や定義も取得できます。
grpcurl — 接続先とサービス名は置き換える# サービス一覧(server reflection 使用) $ grpcurl <your-host>:443 list # サービスの定義を確認 $ grpcurl <your-host>:443 describe example.EchoService # unary RPCを呼び、ヘッダーとtrailersも表示 $ grpcurl -v -d '{"message":"hello"}' \ <your-host>:443 example.EchoService/Echo # TLSを使わないh2c接続では、必要に応じて-plaintextを付ける出力例 (grpcurlのバージョンで表示は異なる)
Resolved method descriptor:
rpc Echo ( .example.EchoRequest ) returns ( .example.EchoResponse );
Request metadata to send: (empty)
Response headers received:
content-type: application/grpc
Response contents:
{
"message": "hello"
}
Response trailers received:
(empty)
grpc-status: 0はワイヤ上のtrailersで送られますが、grpcurlはこれをRPCステータスとして処理するため、成功時の Response trailers received を (empty) と表示するバージョンがあります。ワイヤ上の実際のtrailersはWireshark等と併せて確認してください。
前提: 実際のサービス名、メソッド、TLS、認証、reflectionの有無は接続先によって異なります。
#観測ポイント
| grpcurl | -v で headers / contents / trailers の3点セットを確認する。エラー時は grpc-status と grpc-message を確認する。 |
|---|---|
| DevTools | 一般的なブラウザAPIは、標準gRPCが必要とするHTTP/2制御やtrailersをそのまま公開しない。ブラウザ向けにはgRPC-Webを使い、対応プロキシ等で標準gRPCへ変換する構成が一般的。 |
| Proxy | 標準gRPCはHTTP/2マッピングを前提とする。HTTP/1.1自体にもtrailersはあるが、単純なHTTP/1.1化ではgRPCの意味論は保持されない。gRPC-Web等として明示的に変換するか、HTTP/2とtrailersをエンドツーエンドで維持する必要がある。 |
| tcpdump / Wireshark | 平文(h2c)なら Wireshark が grpc / protobuf ディセクタでデコードできる。フィルタ: grpc。.proto を登録するとメッセージ内容も展開される。 |
| TLS inspection | 装置がh2とtrailersを維持するか確認します。直接接続では成功し、装置経由で UNAVAILABLE になる場合は、プロトコルとtrailersの差を調べます。 |
#関連
gRPC を理解するには土台の HTTP/2(ストリーム、フレーム、trailers)の理解が前提になります。双方向通信の代替としては WebSocket も比較対象です。