Wire Protocol 与数据帧规范¶
gRPC 的通信规约建立在 HTTP/2 之上,官方称之为 gRPC over HTTP/2 Wire Protocol。它精确定义了请求路由、长度前缀帧封装、超时表示法以及响应尾部状态传递的标准。
1. 长度前缀消息封装(Length-Prefixed Framing)¶
在 HTTP/2 的 DATA 帧中,传输的并不是纯裸的 Protobuf 序列化字节,而是包裹了一层 5 字节前缀的复合结构:
+------------------+-----------------------------------+-----------------------------+
| Compressed (1B) | Message Length (4B) | Serialized Message (NB) |
+------------------+-----------------------------------+-----------------------------+
字段细节¶
- Compressed-Flag(1 字节):
0:未压缩,紧接着的数据即为原始 Protobuf 序列化二进制流。1:已启用压缩(采用请求头grpc-encoding中协商的算法,如gzip、snappy或zstd)。- Message Length(4 字节,大端序 Big-Endian):
- 32 位无符号整型,精确指明后续 Protobuf 消息载荷的实际字节大小 $N$。
- Serialized Message($N$ 字节):
- 实际传输的应用层数据实体。
[!NOTE] 流式解包的关键:通过这个固定 5 字节的头部,无论是客户端流还是双向流,接收端都能够精确地在连续的字节流中切分(Framing)出一个个独立的 Protobuf 对象,彻底解决了 TCP 粘包和拆包问题。
2. 请求阶段规范(Request Protocol)¶
gRPC 客户端发起请求时,必须通过一个带 END_HEADERS 的 HTTP/2 HEADERS 帧启动一个新流(Stream):
伪头部(Pseudo-Headers)¶
:method:必须固定为POST。:scheme:http或https。:path:格式严格为/{PackageName}.{ServiceName}/{MethodName}- 示例:
/helloworld.Greeter/SayHello :authority:目标服务器地址与端口(如api.example.com:443)。
标准 gRPC 头部¶
content-type:必须为application/grpc(或者追加子类型application/grpc+proto、application/grpc+json)。te:必须包含trailers(告知代理和对端允许接收 HTTP/2 Trailers 尾部帧)。grpc-timeout:请求截止超时时间,格式由数值和一个时间单位字符组成:H(小时)、M(分钟)、S(秒)、m(毫秒)、u(微秒)、n(纳秒)。- 示例:
grpc-timeout: 500m(超时 500 毫秒)。 grpc-encoding:期望的消息压缩编码(如gzip)。
3. 响应阶段与 Trailers 设计¶
gRPC 将响应划分为两个阶段:
1. Initial-Metadata(响应头):通过第一个 HEADERS 帧返回 :status: 200 和自定义业务头。
2. Response Data(响应体):通过一个或多个 DATA 帧传输带长度前缀的响应消息。
3. Trailing-Metadata(响应尾):通过最后一个带 END_STREAM 标志的 HEADERS 帧传输。gRPC 的调用状态码与错误信息正是位于此处!
sequenceDiagram
participant Client as 客户端
participant Server as 服务端
Client->>Server: HEADERS (:method=POST, :path=/svc/method)
Client->>Server: DATA (5B前缀 + Request Payload, END_STREAM)
Server-->>Client: HEADERS (:status=200, content-type=application/grpc)
Server-->>Client: DATA (5B前缀 + Response Payload)
Server-->>Client: HEADERS (grpc-status=0, grpc-message=OK, END_STREAM)
Trailers 核心字段¶
grpc-status:gRPC 标准状态码(0 代表OK,4 代表DEADLINE_EXCEEDED等)。grpc-message:经 URL 百分号编码的错误提示字符串。grpc-status-details-bin:携带二进制 Protobuf 富错误对象(包含更为丰富的结构化错误细节)。
4. Trailers-Only 优化机制¶
如果服务端在收到请求进行校验时发现错误(例如鉴权失败或资源不存在),根本无需写入任何响应体数据。
此时 gRPC 会触发 Trailers-Only 极速优化:服务端直接返回单个包含 END_STREAM 标志的 HEADERS 帧,将 HTTP 状态码与 gRPC 状态合并发送:
HTTP/2 200 OK
content-type: application/grpc
grpc-status: 16 (UNAUTHENTICATED)
grpc-message: Missing or invalid authorization token
[END_STREAM]
这避免了先发头部、再发空数据、再发尾部的三次帧往返损耗,极大提升了错误场景下的系统防御吞吐量。