nginx websocket连接优化核心是透传upgrade/connection头、关闭缓冲与缓存、按心跳间隔设置proxy_read_timeout(如心跳30秒则设45–60秒)、并调优系统级文件描述符及内核参数。

WebSocket 连接本身不走传统 HTTP 连接池(如 keepalive 连接复用),Nginx 对它的“连接池管理”实质是长连接生命周期的稳定承载与资源调度——重点不在复用,而在不中断、不堆积、不泄漏。优化核心是让 Nginx 放弃按 HTTP 短连接逻辑回收资源,转而配合 WebSocket 的心跳机制持续维持通道。
透传升级头,确保连接真正建立
若握手阶段失败,后续所有“连接池”优化都无意义。Nginx 必须原样转发关键协议信号:
- proxy_http_version 1.1; —— WebSocket 升级强制要求,缺则直接降级为 HTTP/1.0,握手失败
- proxy_set_header Upgrade $http_upgrade; —— 动态转发原始 Upgrade 值(如 websocket、graphql-ws),避免写死导致多协议兼容失效
- proxy_set_header Connection "upgrade"; —— 引号和小写 upgrade 缺一不可;不能用 $http_connection(可能含 keep-alive,会干扰升级语义)
关闭缓冲与缓存,避免连接“假活跃”
缓冲区会截断帧流、延迟转发,缓存可能把 Upgrade 请求当成普通 GET 返回 200,造成连接看似建立实则未升级:
- proxy_buffering off; —— 禁用响应体缓冲,消息到达即透传,防止帧粘包或滞留
- proxy_cache off; —— 显式关闭缓存,杜绝 Upgrade 请求被缓存命中
- proxy_cache_bypass $http_upgrade; —— 兜底策略,带 Upgrade 头的请求一律绕过缓存
超时设置需贴合心跳节奏,而非“越长越好”
proxy_read_timeout 不是设成 0 或 86400 就万事大吉,它必须略大于后端心跳间隔,否则空闲期仍会被误杀:
- 若后端每 30 秒发一次 ping,proxy_read_timeout 至少设为 45~60 秒,留出网络抖动余量
- proxy_send_timeout 同步设为相同值,避免大消息分片发送中途被切断
- keepalive_timeout 可设为相同值,确保客户端到 Nginx 的 TCP 连接不因空闲关闭
- 切忌设为 0:旧版 Nginx 可能无法正确释放异常连接,最终耗尽 fd
系统级资源扩容,支撑真实并发连接数
Nginx worker 能维持多少并发 WebSocket 连接,取决于 OS 层限制,而非配置文件里写的数字:
- 在 /etc/security/limits.conf 中添加:
* soft nofile 1048576
* hard nofile 1048576 - 在 /etc/sysctl.conf 中调优内核:
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535 - Nginx 主配置中同步设置:
worker_rlimit_nofile 1048576;
events { worker_connections 65535; }











