要让 nginx + keepalived 支撑 websocket 长连接集群,需三者协同:nginx 必须透传升级请求并长超时,keepalived 健康检查须验证 http 101 状态码,后端需共享会话状态并配合客户端重连。

要让 Nginx + Keepalived 真正支撑 WebSocket 长连接集群,关键不是堆叠组件,而是打通协议层、连接层和高可用层的协同逻辑。Keepalived 只管 VIP 漂移和节点生死,它不碰 WebSocket 数据;Nginx 必须正确透传升级请求并维持连接;后端服务还需保障会话连续性。三者缺一不可。
WebSocket 连接必须由 Nginx 原生透传
Nginx 默认不识别 WebSocket 协议,需显式启用升级机制:
- 在
location块中强制使用 HTTP/1.1:proxy_http_version 1.1; - 透传升级头:
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "upgrade"; - 禁用缓冲与重定向:
proxy_buffering off;、proxy_redirect off; - 超时设为长周期(如 24 小时):
proxy_read_timeout 86400;、proxy_send_timeout 86400;
Keepalived 健康检查必须验证 WebSocket 升级能力
只检测 Nginx 进程或 HTTP 200 是无效的——进程可能存活但无法完成 WebSocket 握手(HTTP 101)。必须脚本化检查:
- 编写检测脚本(如
/etc/keepalived/chk_ws.sh),用curl -I -s -o /dev/null -w "%{http_code}" http://127.0.0.1/ws-test请求一个真实 WebSocket 路径 - 仅当返回码为
101才认为健康;否则退出非零码,触发 Keepalived 降权或释放 VIP - 在
keepalived.conf中通过vrrp_script引入该脚本,并设置interval 2秒高频探测
后端需保障 WebSocket 会话一致性
VIP 漂移本身不中断已有连接,但新连接若被分发到无状态后端,可能导致消息丢失或重复订阅。应结合:
- 客户端主动重连机制(带退避策略)
- 后端使用共享会话存储(如 Redis Pub/Sub 或分布式 session store)同步连接状态
- Nginx 启用
ip_hash或基于 Cookie 的 sticky session(适用于非跨域场景) - 避免在 Keepalived 切换期间重启 Nginx worker,保留已有连接 fd
内核与系统级调优不可忽略
长连接对系统资源消耗显著,尤其在万级并发下:
- 增大文件描述符限制:
fs.file-max = 2097152,并在 Nginx 中设worker_rlimit_nofile 65535; - 优化 TCP 参数:
net.ipv4.tcp_fin_timeout = 30、net.ipv4.tcp_tw_reuse = 1、net.core.somaxconn = 65535 - 关闭 swap(
vm.swappiness = 0),防止内存压力下连接被交换出物理内存 - 确保时间同步(
chronyd),避免因时间跳变导致 TLS 握手失败或心跳超时误判











