Nginx中WebSocket会话持久化依赖绑定机制确保同一连接始终路由至同一后端,而非记忆用户;需配合ip_hash或sticky cookie、透传Upgrade/Connection头、延长proxy_read_timeout、禁用proxy_buffering及精确location匹配协同生效。

WebSocket 会话持久化在 Nginx 中不是靠“记住用户”实现的,而是靠确保**同一客户端连接始终被路由到同一台后端服务器**。因为 WebSocket 是长生命周期、有状态的双向通道,一旦连接被轮询到不同后端,消息就会丢失、心跳失效、连接异常断开(如报错 1006 或 Unexpected response code: 200)。
必须启用会话绑定机制
默认的 round-robin 负载均衡策略会把后续帧随机分发,破坏连接连续性。需显式配置绑定方式:
- ip_hash:按客户端 IP 哈希固定后端,适合公网 IP 稳定、无代理或 CDN 直连场景;注意 IPv6 和 NAT 环境下可能效果打折
-
sticky cookie(如 upstream_hash 或第三方模块):Nginx Plus 支持
sticky cookie,开源版可通过upstream_hash模块或配合后端下发的 session ID 实现;更适用于移动端、CDN 或 IP 经常变化的情况 -
hash $http_sec_websocket_key:利用 WebSocket 握手时唯一的
Sec-WebSocket-Key做哈希,确保同一次握手的所有帧落在同一节点(注意该值每次新建连接都会变,不跨连接复用)
绑定必须与超时和升级头协同生效
光有绑定不够,若连接中途被断开,重连时仍可能落到新节点。因此要同步保障连接不被误杀:
- 透传
Upgrade和Connection头,确保 101 升级成功(否则根本建不起长连接) -
proxy_read_timeout设为远大于心跳间隔(例如心跳 30 秒 → 至少设 90 秒,推荐 86400) - 禁用
proxy_buffering,避免帧堆积延迟导致心跳超时判定
路径与 location 需精确隔离
会话绑定只在匹配到对应 location 时才起作用。务必避免用宽泛的 location / { ... } 匹配 WebSocket 流量:
- 使用明确路径,如
location /ws/或location ^~ /api/v1/ws - 可加校验逻辑防止误入:
if ($http_upgrade != "websocket") { return 403; } - 确保
upstream块中启用了keepalive 32,减少后端建连开销,提升绑定稳定性
HTTPS 下的注意事项
WSS 连接本身不改变绑定逻辑,但 SSL 终止位置会影响 header 可见性:
- 若 SSL 在 Nginx 终止,
$http_upgrade等变量正常可用,绑定照常工作 - 若 SSL 终止在前端 LB(如云厂商 SLB),需确认它是否透传
Upgrade和Sec-WebSocket-Key,否则 Nginx 收不到关键字段,绑定和升级都会失败 - 务必启用
ssl_protocols TLSv1.2+,旧协议可能干扰升级流程


















