nginx支撑websocket长连接需同步做好三件事:透传upgrade等协议头、按业务空闲周期调优proxy_read_timeout等超时参数、配置ip_hash/least_conn/sticky cookie实现连接粘性,缺一不可。

要让 Nginx 负载均衡真正支撑 WebSocket 长连接的高性能集群,不能只靠加几个参数,关键在于三件事同步到位:协议升级头必须透传、超时时间必须匹配业务空闲周期、后端路由必须保持连接粘性。缺一不可,否则会出现 101 升级失败、60 秒准时断连、或消息被发到错误节点等典型问题。
透传 WebSocket 协议升级头
WebSocket 握手本质是 HTTP/1.1 的 Upgrade 请求,Nginx 必须原样把关键头部转发给后端,否则后端收不到升级意图:
- proxy_http_version 1.1:必须显式声明,HTTP/1.0 不支持 Upgrade 机制
- proxy_set_header Upgrade $http_upgrade:变量名严格小写,$http_upgrade 是客户端原始值(如 websocket)
- proxy_set_header Connection $connection_upgrade:配合 map 块动态设置,避免普通 HTTP 请求被误设为 upgrade
推荐写法(防错更稳):
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
设置匹配业务节奏的超时参数
WebSocket 没有请求-响应周期,空闲时无数据流。Nginx 默认 60 秒超时会主动断开连接,需按实际心跳和网络状况调优:
- proxy_read_timeout:设为业务最长空闲间隔的 2–3 倍。例如后端心跳 30 秒,建议设 90s;IoT 设备上报间隔 5 分钟,可设 300–600s
- proxy_send_timeout:一般无需大幅调整,除非后端响应大消息特别慢(如批量推送)
- keepalive_timeout:建议与 proxy_read_timeout 一致或略短,保证客户端到 Nginx 连接不提前中断
确保连接始终路由到同一后端节点
WebSocket 连接建立后,所有后续帧都必须到达最初握手的后端,否则状态丢失、消息乱序:
- ip_hash:最简单,适合公网直连场景;但 NAT 环境下多个用户共用一个 IP,易导致单点过载
- least_conn:适合后端性能差异大、连接数波动剧烈的混合部署(如同时跑 WebSocket 和 HTTP API)
-
sticky cookie(如 sticky cookie srv_id expires=1h):最可靠,首次响应种 Cookie,后续按 Cookie 路由,不受 IP 变化影响;需确认 Nginx 编译时启用了
ngx_http_sticky_module
补充:upstream 层级优化
在 upstream 块中加入基础连接管理,提升集群稳定性:
- keepalive 32:保持与每个后端的空闲长连接池,减少重复建连开销
- max_fails=2 fail_timeout=10s:快速剔除异常节点,避免将新连接打到已断连的后端
- 避免使用默认轮询(round-robin),它对长连接完全不适用











