无法在NGINX中读取gRPC请求头的问题求助
解决OpenResty读取gRPC客户端自定义请求头的问题
问题根源
gRPC的自定义元数据通过HTTP/2传输,OpenResty处理这类请求时,得注意头名的大小写、Lua代码的执行时机,还要确保NGINX没把自定义头过滤掉。
具体解决步骤
1. 选对Lua代码的执行时机
得在grpc_pass转发请求之前的阶段(比如access_by_lua_block)读取请求头,要是等请求已经发往后端了,再读就晚了。
给个NGINX配置的例子:
server { listen 443 ssl http2; server_name your-domain.com; ssl_certificate /path/to/cert; ssl_certificate_key /path/to/key; location /your.grpc.service { # 转发前先执行Lua读头 access_by_lua_block { local headers = ngx.req.get_headers() # 先遍历所有头,看看有没有收到自定义头 for k, v in pairs(headers) do ngx.log(ngx.ERR, "收到头: ", k, " => ", v) end # 用完全匹配的小写头名读取(gRPC元数据转HTTP/2后是小写) local custom_header = headers["custom-header-name"] if custom_header then ngx.log(ngx.ERR, "找到自定义头: ", custom_header) else ngx.log(ngx.ERR, "没找到自定义头") end } grpc_pass grpc://your-grpc-backend:50051; # 如果要把自定义头传给后端服务,加这句 grpc_pass_header custom-header-name; } }
2. 严格匹配gRPC元数据的HTTP/2映射规则
gRPC的文本元数据要求头名必须是小写字母开头,只能包含小写字母、数字、连字符,你的custom-header-name是符合要求的。传输时头名会原样保留,所以Lua里必须用custom-header-name这个完全一致的key读取,别换成下划线版本。
3. 确认OpenResty版本支持gRPC
得用OpenResty 1.13.6.1及以上的版本,Docker镜像直接用官方的openresty/openresty稳定版就行,别用太老的版本。
4. 验证客户端确实发了元数据
在Go客户端加个日志,确认元数据已经正确附在请求上下文里:
md, ok := metadata.FromOutgoingContext(ctx) if ok { log.Printf("发送的元数据: %v", md) }
额外提醒
- 要是想在Lua里改或者加gRPC元数据,用
ngx.req.set_header()就行,但头名得符合gRPC的规则。 grpc_pass_header是控制哪些头传给后端gRPC服务的,要是只是NGINX自己读头,不用配这个。
内容的提问来源于stack exchange,提问作者Ben Zini
相关产品推荐
相关产品推荐

