Nginx需配置透传Upgrade和Connection头并调大超时值才能代理WebSocket连接;须设proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade",并设置proxy_read_timeout等为300秒以上。

Nginx 默认不直接支持 WebSocket 协议的长连接升级,但通过正确配置 HTTP 头和连接保持机制,可以成功将 WebSocket 请求(如 GraphQL 订阅)代理到后端 GraphQL 服务(如 Apollo Server、GraphQL Yoga 或 Hasura)。关键在于让 Nginx 透传 Upgrade 和 Connection 头,并维持连接不超时。
启用 WebSocket 升级头透传
Nginx 必须显式允许并转发客户端发起的协议升级请求。默认情况下,它会过滤掉 Upgrade 和 Connection 头,导致 WebSocket 握手失败(返回 400 或直接断连)。
- 在
location块中添加以下指令:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
其中 $http_upgrade 是 Nginx 内置变量,能动态捕获客户端请求中的 Upgrade: websocket;Connection "upgrade" 需加引号,避免被当作指令解析。
调整超时与连接保持参数
WebSocket 是长连接,Nginx 的默认超时(如 proxy_read_timeout 60s)会导致连接被意外关闭,订阅中断。
- 建议设置较长的读写超时(例如 300 秒或更久,视业务需要):
proxy_send_timeout 300;
proxy_connect_timeout 75;
若使用 keepalive 连接到上游(如 Node.js 后端),还可添加 proxy_http_version 1.1 + proxy_set_header Connection '' + proxy_pass_request_headers on 来复用连接。
匹配 GraphQL 订阅路径(常见实践)
多数 GraphQL 服务将订阅统一暴露在 /graphql 路径,靠 operationName 或 query 内容区分查询/变更/订阅。但更稳妥的做法是为订阅单独设路由(如 /graphql/subscriptions),便于 Nginx 精准配置。
- 示例配置片段(针对独立订阅端点):
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300;
proxy_send_timeout 300;
}
前端客户端初始化订阅时,需指定该路径(如 Apollo Client 的 subscriptionClient URL 设为 wss://your-domain.com/graphql/subscriptions)。
HTTPS + WSS 注意事项
生产环境务必使用 TLS。Nginx 终止 HTTPS 后,WebSocket 升级走的是内部 HTTP 连接(即 proxy_pass http://...),无需额外配置 wss。只要证书有效、前端用 wss://、Nginx 正确透传升级头,即可自动协商加密 WebSocket。
- 检查点:
- 确保 SSL 证书已加载且未过期(
ssl_certificate和ssl_certificate_key) - 前端连接地址必须为
wss://,不能是ws://(浏览器会拒绝) - 后端服务无需开启 HTTPS,Nginx 已完成 TLS 卸载










