云服务器 WebSocket 空闲后频繁断开:查 Nginx 超时、心跳与负载均衡,再评估扩容

网页上的实时消息连接刚建立时正常,空闲一段时间就断开;刷新又能连上。看到"断线",不应直接买更大带宽:WebSocket 是长连接,断开可能发生在客户端、云服务器上的 Nginx、应用或前面的负载均衡。先量出断开前最后一次收发数据到断开的间隔,再定位是哪一层主动关闭。

本文适用于 Linux 云服务器上用 Nginx 反向代理 WebSocket 服务的场景,可选地包含云负载均衡。示例路径、端口和超时时间都只是检查模板,必须按实际环境、流量与变更流程调整;不要在生产高峰直接大幅放宽所有连接超时。

先画清链路,别把所有断线都叫"带宽不足"

典型路径是浏览器或 App → 公网入口/负载均衡 → Nginx → 应用。连接建立时要看到协议升级成功(常见为 HTTP 101 Switching Protocols),之后的数据不再是普通短请求。浏览器开发者工具 Network 的 WS 面板可以记录连接建立、最后一帧、关闭码与时间;同时对齐应用日志、Nginx 日志和负载均衡日志。若总在相近的空闲间隔断开,优先查空闲超时及心跳;若只在连接数高峰断,才重点查连接容量、文件描述符和实例资源。

注意"连接持续了 60 秒"和"最后一帧之后空闲了 60 秒"不是同一件事。Nginx 官方解释,proxy_read_timeout 计的是从上游读取数据时两次读操作之间的间隔,默认 60 秒,而不是整个 WebSocket 会话的总寿命。服务器周期性发送 WebSocket Ping 帧也可重置相应超时。Nginx WebSocket 代理说明、Nginx proxy_read_timeout 定义

第一步:确认升级请求确实经过预期的 Nginx 配置

先读取当前生效配置,不要凭某个旧的配置文件判断:

bash 复制代码
sudo nginx -t
sudo nginx -T 2>&1 | less

核对 WebSocket 路径实际命中的 server、location、proxy_pass、Upgrade 和 Connection 头,以及 proxy_read_timeout。Nginx 官方示例要求显式传递升级相关头;不同 Nginx 版本的上游 HTTP 版本默认值可能不同,老版本尤其要核对 proxy_http_version 1.1。以下是示意片段,不是可以不改就粘贴上线的完整配置:

nginx 复制代码
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    location /ws/ {
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 120s;
    }
}

120s 只是说明"要与心跳和前置入口的策略匹配",不是推荐所有业务统一设置。改动前保存配置,使用 nginx -t 检查,按维护流程重载,再复测;避免把 proxy_read_timeout 错当带宽或连接数限制。Nginx WebSocket 代理说明

第二步:心跳与前置负载均衡分别验证

如果没有负载均衡,先在同一浏览器会话里比较"持续有消息"和"完全空闲"的断开间隔。若应用支持服务端 Ping/Pong,记录 Ping 发出、Pong 收到和异常关闭时间;心跳间隔应小于链路上相关空闲超时,并保留抖动余量。不要依赖浏览器端 JavaScript 直接发送协议级 Ping------浏览器 WebSocket API 不暴露这个操作;也可以用应用层消息做保活,但要让服务端按协议与业务语义处理。

如果前面还有云负载均衡,用相同客户端分别走"负载均衡域名"和经过授权的"直连 Nginx 测试入口"。只有前者断线,优先核对该负载均衡产品、类型及监听器/后端的空闲超时、健康检查和访问日志。不同产品对 WebSocket 的超时规则不同,不能照搬某厂商的默认秒数。AWS ALB 属性文档、Google Cloud 负载均衡 WebSocket 超时说明

直连测试须保留 TLS、Host/SNI、认证与安全组边界,不要为了排障把应用端口公开到全网。若连直连也断,再看 Nginx 和应用日志里的主动关闭、异常退出、部署重启或会话状态问题。

第三步:判断是不是容量问题,再考虑买资源

若断线集中在并发高峰,而不是固定空闲间隔,再同时观察云服务器 CPU、内存、网络吞吐/丢包、活跃连接数、文件描述符与应用事件循环延迟。例如先做只读检查:

bash 复制代码
ss -s
cat /proc/net/sockstat
systemctl show nginx -p LimitNOFILE

还应查 Nginx worker_connections、应用自身连接上限、云监控峰值与实际 WebSocket 消息字节量。一个 WebSocket 连接会长期占用连接槽位,但"连接很多"不等于"带宽已满";心跳太频繁也会放大不必要的流量。若需要扩为多台云服务器,确认负载均衡支持所需连接模式、会话/订阅状态可跨实例恢复,并做断线重连演练,不能只增加实例数。

验证与常见误区

修复后至少做三类测试:持续有消息的长连接、无业务消息的空闲连接、业务峰值下的多连接。分别记录握手成功率、最后一帧到关闭的间隔、异常断线率、重连成功率和服务器资源;再用相同客户端对比经负载均衡与直连路径。变更后一段时间仍要观察,而不是看到一次连接超过两分钟就收工。

常见误区有五个:把固定空闲超时当带宽瓶颈;只调大 Nginx 超时却忽略更短的前置负载均衡超时;只看 TCP keepalive 而不验证应用层消息/协议 Ping;给所有连接设置极长超时却不预算长期占用的资源;增加云服务器却没有处理跨实例会话与重连。

最终购买决策应回到证据:如果断线源于超时或心跳设置,先修配置;如果在真实并发峰值中连接槽位、内存或网络指标持续接近上限,再据实测连接数、每连接资源、消息吞吐及冗余目标选择升级单台云服务器、增加实例或购入合适的负载均衡。不要用"WebSocket 断了"一个现象直接推导出带宽规格。

相关推荐
Linux界最忧郁之人1 小时前
OpenStack Victoria双节点实战|Packstack一键部署(CentOS‑Stream‑8)+华为云ECS实操
linux·运维·服务器·centos·华为云·openstack
DevNote_1 小时前
1C1G 服务器从零配置实录(附完整命令)
linux·运维·服务器·javascript·adb·ssh·gmssh
进击的荆棘1 小时前
Linux系统——进程信号之保存和捕捉信号
linux·运维·服务器·信号处理·信号
开开心心就好1 小时前
免安装PDF盖章工具,透明度和位置可调
运维·服务器·前端·javascript·pdf·ocr·1024程序员节
0+11110 小时前
Linux --从 poll 到 epoll多路转接
linux·服务器·1024程序员节
青瓦梦滋10 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
桌面运维家11 小时前
旧电脑跑不动课程软件,VDI云桌面怎样接着用?
运维·服务器·虚拟化·pve·vdi·云桌面
zhang1338308907511 小时前
传统机械三杯式风速传感器易磨损冻堵?CG-88金属超声波风速风向传感器给出免运维方案
运维·服务器·网络·人工智能·自动化
知已难寻11 小时前
第 2 篇 · 云的地基:服务器、存储、网络三大基础设施
运维·服务器·网络·云原生·云计算·负载均衡·1024程序员节