Trailer 是什么
Trailer 是响应头(请求也可用),用来预告「在分块报文的尾部还会出现哪些字段」。它解决的是「值要等实体生成完才知道」的问题:服务端各阶段耗时、内容完整性摘要、gRPC 调用状态这类信息只能在内容结束之后才产生(RFC 9110 §6.5.1)。
基本信息
| 名称 | Trailer |
|---|---|
| 方向 | 响应头(请求亦可使用) |
| 规范 | RFC 9110 §6.5.1 |
| 前提 | 报文使用 Transfer-Encoding: chunked |
| 相关 | 请求头 TE 声明 trailers 表示客户端愿意接收 |
| 典型用途 | Server-Timing、gRPC 的 grpc-status 与 grpc-message |
典型使用场景
- gRPC:调用状态与错误信息在报文尾部传输
- 性能观测:Server-Timing 在内容结束后给出各阶段耗时
- 网关配置核查:确认代理是否保留 trailer(默认经常被丢弃)
- 排障:curl 抓到了分块响应却看不到末尾字段
- 协议实现者:正确解析分块报文尾部的字段书写
- 流式接口设计:判断哪些元数据适合放尾部而非头部
报文结构
报文结构
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Trailer: Server-Timing # 预告尾部会出现哪些字段
5
hello
0
Server-Timing: db;dur=53, app;dur=8 # 内容结束后才产生的值抓取观察
抓取观察
# 用 curl 观察分块与尾部(需较新版本)
curl -s --raw -D - https://api.example.com/slow | tail -5
# 若网关把 trailer 丢了,这里只能看到普通头部,看不到末尾字段chunked 报文结构
| 部分 | 内容 | 说明 |
|---|---|---|
| 状态行与头部 | 含 Trailer 声明 | 预告尾部会出现哪些字段名 |
| 分块体 | 长度 + 数据交替出现 | 长度用十六进制表示 |
| 结束块 | 长度为 0 | 表示实体内容结束 |
| 尾部字段 | Server-Timing 等 | 只有声明过且客户端接受才会发送 |
尾部发送的字段应当在 Trailer 里声明;未声明的字段接收方可以忽略,漏声明等于白送。
网关是 trailer 最常见的丢失点:Nginx 需通过 grpc_pass(HTTP/2 明文 h2c)转发 gRPC 调用才能完整传递尾部状态,普通反向代理链路多会丢弃。
非分块报文不能携带尾部字段:用 Content-Length 声明的响应没有 trailer,这是排障时最容易忽略的前提。