Nginx WebSocket代理高可用需从连接路由、复用、故障转移三方面协同配置:用ip_hash或least_conn保证同一客户端固定后端;upstream启用keepalive并调优参数;延长proxy超时、启用健康检查与自动重试;透传Upgrade头并关闭buffering。

Nginx WebSocket 代理要实现高可用,关键不是堆功能,而是让 upstream 与 WebSocket 的长连接、有状态、低频交互特性真正对齐。默认的轮询或简单哈希容易导致连接中断、消息丢失或后端过载,必须从连接路由、连接复用、故障转移三方面协同配置。
用 ip_hash 或 least_conn 做连接级路由
WebSocket 连接一旦建立,后续所有帧都依赖该 TCP 通道,不能像 HTTP 请求那样随意换节点。因此 upstream 必须保证同一客户端始终落到同一后端:
- ip_hash:最常用,适合 Web 端 IP 稳定的场景。Nginx 根据客户端真实 IP 哈希固定后端,配置简洁可靠
- least_conn:更适合移动端或 IP 频繁变化的场景。它动态选择当前活跃连接数最少的节点,在长连接密集型服务中能更均衡地分摊压力,实测可降低约 23% 的请求等待时间
- 避免纯轮询(round-robin):同一用户可能在重连时被分到不同节点,导致会话丢失、消息不达
upstream 内启用 keepalive 并合理设参
后端与 Nginx 之间的连接也应复用,减少握手开销和 TIME_WAIT 积压:
- 在 upstream 块中添加 keepalive 32(数值按并发连接规模调整,一般 16–64 足够)
- 配合设置 keepalive_requests 1000 和 keepalive_timeout 60s,防止单个长连接过度占用资源
- 注意:keepalive 是指 Nginx 与后端服务器之间的连接池,不是客户端到 Nginx 的 WebSocket 连接
配合 proxy_* 超时与健康检查防断连
高可用不仅靠“分得对”,还要“不断连”“自动切”:
- 延长 proxy_read_timeout 和 proxy_send_timeout(如设为 86400),避免空闲 WebSocket 连接被 Nginx 主动关闭
- 设置 proxy_connect_timeout 60,给握手阶段留足网络延迟余量
- 启用 proxy_next_upstream error timeout http_502 http_503 http_504,让失败连接自动转发到其他健康节点
- 通过 max_fails=3 fail_timeout=30s 定义故障判定标准;若需主动探测,可结合第三方 health_check 模块或自建 /health 端点 + custom check
协议头透传与升级逻辑不可省略
哪怕 upstream 配置再稳,如果握手阶段协议升级失败,连接根本建不起来:
- 必须写 proxy_http_version 1.1 —— WebSocket 升级只在 HTTP/1.1 中定义
- 用 map 动态设置 Connection 头:map $http_upgrade $connection_upgrade { default upgrade; '' close; },再配 proxy_set_header Upgrade $http_upgrade 和 proxy_set_header Connection $connection_upgrade
- 禁用 proxy_buffering on(应设为 off),避免 Nginx 缓存并延迟转发 WebSocket 帧


















