要让 nginx 稳定代理 grpc 流量,必须启用 https 下的 http/2、使用 grpc_pass 替代 proxy_pass、禁用缓冲、延长超时并复用连接;否则易出现 426、502 或“stream removed”错误。

要让 Nginx 稳定代理 gRPC 流量,核心不是套用 HTTP 反向代理模板,而是围绕 grpc_pass 构建一整套适配 HTTP/2 和流式通信的配置体系。漏掉任一关键项(如 HTTP/2 启用、缓冲禁用、连接复用),都可能引发 426、502 或 “Stream removed” 等典型错误。
必须启用 HTTP/2 并绑定 TLS
gRPC 严格依赖 HTTP/2,而 Nginx 仅在 HTTPS 监听下才允许启用 http2(明文 h2c 在生产中不被推荐且客户端支持差):
- server 块中监听语句必须含 ssl http2,例如:
listen 443 ssl http2; - 配置有效证书:使用
ssl_certificate和ssl_certificate_key指向 PEM 文件 - 禁用老旧协议:
ssl_protocols TLSv1.2 TLSv1.3;,避免协商失败 - 注意:Nginx 1.25+ 版本中,
http2 on;需单独写在 server 块内,不可再塞进 listen 指令
正确使用 grpc_pass 替代 proxy_pass
这是最易混淆的关键点——gRPC 流量必须用 grpc_pass,它自动启用 HTTP/2 协议栈并透传二进制帧;proxy_pass 会降级为 HTTP/1.1,直接导致失败:
- 后端为明文 gRPC(如 Go 默认服务):
grpc_pass grpc://127.0.0.1:50051; - 后端也启用了 TLS(双向认证等场景):
grpc_pass grpcs://127.0.0.1:50051;,并配合grpc_ssl_verify off;(测试)或完整证书链(生产) - 若需负载均衡,先定义 upstream 块,再在 grpc_pass 中引用:
grpc_pass grpc://my_grpc_backend;
关闭缓冲与调优长连接超时
gRPC 是长连接、双向流式通信,Nginx 默认的缓冲和短超时会截断响应或主动断连:
- 禁用内部缓冲:
grpc_buffering off;(防止粘包、延迟或状态错乱) - 延长读写超时:
grpc_read_timeout 3600;和grpc_send_timeout 3600;(单位秒,适应空闲流或大文件传输) - 启用连接池复用:
upstream块中添加keepalive 2000;和keepalive_timeout 75s;,大幅减少 TIME_WAIT 连接数
验证与调试要点
别用 curl 测试——它不理解 gRPC 的二进制帧和 HTTP/2 语义。务必使用专业工具:
- 用
grpcurl -insecure -plaintext your-domain.com:443 package.Service/Method发起真实调用 - 检查 Nginx error.log,重点关注:
upstream rejected request、connection reset by peer、no live upstreams - 确认后端监听地址为
0.0.0.0:50051(而非仅127.0.0.1),尤其在 Docker 或 Windows 环境下 - Windows 用户注意:官方 Windows 包不含 grpc 模块,需换用 mzsanford 等第三方预编译版











