首頁 > 軟體

gRPC 的協定分析

2020-06-16 17:34:24

gRPC 和通常的基於TCP的實現不同,是直接基於HTTP2 協定的。HTTP2 使得grpc 能夠更好的適用於移動用戶端和伺服器端通訊的使用場景,並且連線多路複用也保證了RPC 的效率。

gRPC 的協定設計上很好的使用了HTTP2 現有的語意,請求和響應的資料使用HTTP Body 傳送,其他的控制資訊則用Header 表示。先看個例子,假設Protobuf 定義如下:

package foo.bar;

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

service HelloService {
  rpc SayHello(HelloRequest) returns (HelloResponse);
}

在這裡面我們定義了一個service HelloService。grpc 為這樣一個呼叫傳送的請求為:

HEADERS (flags = END_HEADERS)
:method = POST
:scheme = http
:path = /foo.bar.HelloService/SayHello
:authority = api.test.com
grpc-timeout = 1S
content-type = application/grpc+proto
grpc-encoding = gzip
authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v

DATA (flags = END_STREAM)
<Delimited Message>

Http 請求的Path 部分用來表示呼叫哪個服務,格式是/{package}.{ServiceName}/{RpcMethodName},content-type 目前取值都是application/grpc+proto,將來grpc 支援除Protobuf 之外的協定如Json 時,會有別的值。grpc-encoding 可以有gzip, deflate, snappy 等取值,表示採用的壓縮方法。grpc-timeout 表示呼叫的超時時間,單位有Hour(H), Minute(M), Second(S), Millisecond(m), Microsecond(u), Nanosecond(n) 等。

除了grpc 定義的標準頭之外,也可以自己新增新的頭。如果是二進位制的Header,則Header Name 以-bin 結尾,Header Value 是經過Base64 編碼的二進位制資料。

伺服器端對這個請求返回一個Response:

HEADERS (flags = END_HEADERS)
:status = 200
grpc-encoding = gzip

DATA
<Delimited Message>

HEADERS (flags = END_STREAM, END_HEADERS)
grpc-status = 0 # OK
trace-proto-bin = jher831yy13JHy3hc
grpc-status 為0 表示請求沒有出現問題,成功返回。

grpc 還定義了GOAWAY Frame, 當Server 斷開一個連線的時候,需要向用戶端傳送這樣一條訊息;以及PING Frame,接受到PING Frame 後直接原樣返回資料,用於連線存活檢測和延遲檢測。

HTTP2 的Header 並不是特別高效的格式,儲存上和解析上都有一些效率問題。如果啟用加密連線的話,則會有更多的效率開銷。

本文永久更新連結地址http://www.linuxidc.com/Linux/2016-08/134725.htm


IT145.com E-mail:sddin#qq.com