nginx反向代理grpc需严格遵循http/2协议:启用https+http/2监听、使用grpc_pass而非proxy_pass、配置upstream负载均衡、关闭缓冲并调优超时、透传grpc头及增强可观测性。

要用 Nginx 反向代理 gRPC 流量并支撑微服务高性能中转与负载均衡,关键不是套用 HTTP 代理那一套,而是严格对齐 gRPC 的协议本质:它运行在 HTTP/2 之上,依赖二进制帧、多路复用和双向流。配置错一个基础项——比如监听没写 http2、用了 proxy_pass、忘了关缓冲——就会出现 426 Upgrade Required、502 Bad Gateway 或 Stream removed 等典型错误。
必须启用 HTTPS + HTTP/2 监听
gRPC 客户端(如 Go、Java SDK)默认只发起 TLS 加密的 HTTP/2 连接,Nginx 必须在 443 端口终止 TLS 并启用 HTTP/2,不能走明文 h2c(生产环境不推荐,兼容性差):
-
listen 443 ssl http2;——http2必须紧跟在listen指令后(Nginx 1.25+ 需单独加http2 on;在server块内) - 配真实或有效自签名证书:
ssl_certificate和ssl_certificate_key指向 PEM 文件 - 禁用老旧协议:
ssl_protocols TLSv1.2 TLSv1.3;,避免协商失败降级
只用 grpc_pass,不用 proxy_pass
proxy_pass 会强制降级为 HTTP/1.1,直接破坏 gRPC 流语义;grpc_pass 是唯一能透传二进制帧、维持 HTTP/2 连接的指令:
- 后端是明文 HTTP/2(推荐):
grpc_pass grpc://grpc_backend;(配合upstream) - 后端也启用了 TLS(如 mTLS):
grpc_pass grpcs://grpc_backend;,并配grpc_ssl_verify off;(测试)或完整 CA 链(生产) - 定义 upstream 实现负载均衡:
upstream grpc_backend {<br> server 10.0.3.10:8080 max_fails=3 fail_timeout=30s;<br> server 10.0.3.11:8080 max_fails=3 fail_timeout=30s;<br> keepalive 32;<br> }
关闭缓冲并调优长连接行为
gRPC 是长连接、双向流模型,Nginx 默认缓冲和超时策略会截断响应、主动断连或导致状态错乱:
- 禁用内部缓冲:
grpc_buffering off;—— 防止粘包、延迟、grpc-status错位 - 延长读写超时:
grpc_read_timeout 3600;和grpc_send_timeout 3600;(单位秒),适配空闲流、大文件上传等场景 - 复用后端连接池:
keepalive 32;在 upstream 中设置,worker 进程复用空闲 H2 连接,显著降低 TIME_WAIT 和建连开销
透传关键头并补充可观测性
gRPC 元数据(如压缩编码、请求 ID)需显式透传,否则后端可能无法解码或链路追踪中断:
- 透传标准 gRPC 头:
grpc_set_header grpc-encoding $grpc_encoding;、grpc_set_header grpc-accept-encoding $grpc_accept_encoding; - 补充客户端信息:
grpc_set_header X-Real-IP $remote_addr;、grpc_set_header X-Request-ID $request_id; - 开启专用日志格式,记录 gRPC 状态:
log_format grpc '$remote_addr [$time_local] "$request" $status upstream:$upstream_addr rt=$request_time grpc_status=$upstream_http_grpc-status';











