一次生产环境 WebSocket 连接断开的排查与解决
上周五临下班前,测试反馈了一个诡异的问题:测试平台的实时日志功能,大概每过 1 分钟就会自动断开连接,前端报错 `Connection Closed`。
1. 问题复现与初步定位
我在本地开发环境(Localhost)测试了一下,挂机 10 分钟都没有断开。这说明代码本身逻辑没有大问题,大概率是环境差异导致的。
打开浏览器的 Network 面板,观察 WebSocket 连接。发现每次断开的时间点都极其规律:正好是 60 秒。
2. 排查链路
我们的部署架构是:浏览器 -> Nginx (反向代理) -> Django (daphne)。
既然是 60 秒断开,我首先怀疑是 Nginx 的超时配置。查看服务器上的 nginx.conf:
location /ws/ {
proxy_pass http://backend_ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# ❌ 问题就在这里,默认是 60s
# proxy_read_timeout 60s;
}
3. 解决方案
原因找到了:Nginx 默认的 proxy_read_timeout 是 60 秒。如果后端在 60 秒内没有向前端发送任何数据(心跳包),Nginx 就会认为连接超时,主动断开。
修改配置,增加超时时间:
location /ws/ {
# ... 其他配置 ...
proxy_read_timeout 3600s; # 改为 1 小时
proxy_send_timeout 3600s;
}
重启 Nginx 后,问题解决。
4. 反思
这次事故提醒我:在做长连接业务时,心跳机制(Ping/Pong)非常重要。除了依赖 Nginx 的超时配置,应用层也应该每隔 30 秒发送一次心跳包保活。