Nginx 1.13.10+ 可通过 grpc_set_header 将客户端 header 透传为 gRPC metadata,需确认版本与模块支持、正确配置映射规则、处理空值兜底,并验证后端是否成功接收。

gRPC 本身不支持直接在 HTTP/2 层透传自定义 header(尤其是非 grpc- 前缀的 metadata),但 Nginx 在 1.13.10+ 版本中通过 grpc_set_header 指令,可将客户端请求中的 HTTP/2 伪头(如 :authority)或普通 header 注入到上游 gRPC 请求的 metadata 中——前提是后端服务能正确解析这些 metadata。
确认 Nginx 版本与模块支持
Nginx 必须是 1.13.10 或更高版本,且需启用 ngx_http_grpc_module(通常编译时默认开启)。可通过以下命令验证:
若无输出或版本过低,需升级或重新编译 Nginx。
配置 grpc_set_header 透传关键元数据
在 location 块中使用 grpc_set_header,将客户端 header 映射为 gRPC metadata。注意:
– header 名称会自动转为小写并用短横线连接(如 X-Request-Id → x-request-id);
– 后端 gRPC 服务需从 metadata 中读取对应 key(区分大小写,推荐全小写);
– 不要覆盖 grpc-encoding、grpc-encoding-accept 等保留 header。
示例配置:
grpc_pass grpc://backend;
grpc_set_header x-request-id $http_x_request_id;
grpc_set_header x-user-id $http_x_user_id;
grpc_set_header x-forwarded-for $remote_addr;
grpc_set_header authority $host;
}
处理客户端未携带 header 的兜底逻辑
若某些 header 可选,可用 Nginx 变量默认值避免空值透传(空值可能被后端忽略或报错):
- 用
$arg_x_token读取 URL query 参数(如?x_token=abc)作为 fallback - 用
map指令预定义变量,优先取 header,缺失时设默认值 - 避免直接写
grpc_set_header x-token "",这会透传空字符串而非省略该字段
例如:
map $http_x_trace_id $trace_id {default $http_x_trace_id;
"" $arg_x_trace_id;
}
location / {
grpc_pass grpc://backend;
grpc_set_header x-trace-id $trace_id;
}
验证透传是否生效
最直接方式是让后端 gRPC 服务打印接收到的 metadata(如 Go 中用 grpc.Peer().Addr + metadata.FromIncomingContext())。也可用 tcpdump 抓包观察 HTTP/2 frames 中的 HEADERS 帧内容(需解密 TLS 流或使用明文 HTTP/2)。
常见问题排查:
- 客户端未发送对应 header → 检查前端代码或 curl 是否加了
-H "X-User-ID: 123" - Nginx 日志中出现
upstream sent invalid header→ 检查 header 名含非法字符或长度超限 - 后端收不到 metadata → 确认 key 名大小写、是否被中间件过滤、是否用了
grpc_set_header而非proxy_set_header


















