WebSocket 连接失败排查记录
2026年7月9日 server 9 分钟阅读 2 次阅读
一、故障概述
- 故障时间:2026年7月9日 18:00 左右
- 故障现象:https://example.com/ 无法访问
- 控制台报错:
WebSocket connection to 'wss://example.com/' failed
- 影响范围:Web 界面无法使用
- 解决方式:修复 Nginx 配置,添加 WebSocket 支持
- 恢复时间:约 10 分钟
- 根本原因:之前重新申请 SSL 证书时,certbot 自动生成的配置缺少 WebSocket 支持
二、环境信息
| 项目 | 信息 |
|---|---|
| 服务器 | 192.0.2.1 |
| 域名 | example.com |
| 服务 | OpenClaw(Docker,端口 18789) |
| Web 服务器 | Nginx |
三、故障时间线
18:00 - 发现 OpenClaw Web 界面无法访问
18:01 - 查看浏览器控制台,报错 WebSocket 连接失败
18:02 - 检查服务器状态:容器运行正常(healthy)
18:02 - 检查 Nginx:配置语法正常,HTTPS 返回 200
18:03 - 检查 Nginx 配置文件:发现缺少 WebSocket 支持
18:05 - 修复 Nginx 配置,添加 WebSocket 头
18:06 - 重载 Nginx
18:07 - 测试访问,恢复正常
四、排查过程
排查思路
WebSocket 连接失败,排查顺序:
1. 服务端 → 容器是否正常运行
2. Web 服务器 → Nginx 是否正常、配置是否正确
3. 网络层 → SSL 证书、端口、防火墙
4. 客户端 → 浏览器、代理、网络环境
为什么按这个顺序?
- 先排除服务端问题(最简单直接)
- 再查 Web 服务器(Nginx 是中间层)
- 然后查网络层
- 最后查客户端(变量最多)
为什么要检查 Nginx WebSocket 配置?
- 错误信息是
WebSocket connection failed,说明 WebSocket 握手失败 - WebSocket 和普通 HTTP 请求不同,需要特殊的头信息
- Nginx 作为反向代理,如果不配置 WebSocket 支持,会拦截 WebSocket 请求
- certbot 自动配置时只管 SSL,不管应用层功能
第一步:检查服务端状态
docker ps | grep openclaw
结果: 容器正常运行,状态 healthy
结论: 服务本身没问题,问题在 Nginx 或网络层
第二步:检查 Nginx 状态
sudo nginx -t
curl -I https://example.com
结果:
- Nginx 配置语法正常
- HTTPS 返回 200 OK
结论: Nginx 基础功能正常,问题可能在 WebSocket 配置
第三步:检查 Nginx WebSocket 配置
cat /etc/nginx/conf.d/example.conf
发现问题: 配置中缺少 WebSocket 支持的关键配置:
# 缺少的配置
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
为什么会缺少?
之前重新申请 SSL 证书时,certbot 自动生成的配置只包含基础的 HTTP 代理,没有 WebSocket 支持。
第四步:修复 Nginx 配置
执行命令:
echo 'server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
}
}
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}' | sudo tee /etc/nginx/conf.d/example.conf
重载 Nginx:
sudo nginx -t && sudo systemctl reload nginx
五、根因分析
问题链路:
用户访问 Web 界面
↓
浏览器尝试建立 WebSocket 连接(wss://example.com/)
↓
Nginx 收到请求,但没有 WebSocket 头支持
↓
WebSocket 握手失败
↓
页面无法正常工作
根因: 之前重新申请 SSL 证书时,certbot 自动生成的配置没有包含 WebSocket 支持的头信息。
六、关键配置解释
WebSocket 需要的配置
proxy_http_version 1.1; # WebSocket 需要 HTTP 1.1
proxy_set_header Upgrade $http_upgrade; # 告诉后端这是 WebSocket 升级请求
proxy_set_header Connection "upgrade"; # 连接类型设为 upgrade
proxy_read_timeout 86400; # 超时时间设为 24 小时(保持长连接)
为什么 WebSocket 需要特殊配置?
普通 HTTP 请求是一问一答,WebSocket 是长连接(双向通信)。Nginx 默认不知道这是 WebSocket 请求,需要通过 Upgrade 和 Connection 头告诉它。
七、经验总结
1. certbot 自动生成的配置可能不完整
certbot 只管 SSL 证书,不管你的应用需要什么功能。重新申请证书后,需要检查配置是否完整。
2. Nginx 配置修改后要测试
sudo nginx -t # 测试配置语法
sudo systemctl reload nginx # 重载配置
3. heredoc 命令的坑
正确用法:
cat > 文件 << 'EOF'
内容...
EOF # 必须单独一行
看到 > 符号时,说明 shell 在等待结束标记,输入 EOF 回车即可。
更安全的替代方案:
echo '内容' | sudo tee 文件
4. 排查 WebSocket 问题的思路
- 检查服务端是否正常运行
- 检查 Nginx 是否支持 WebSocket(关键配置是否完整)
- 检查 SSL 证书是否有效
- 检查客户端是否有代理/网络问题
八、附录:相关命令
# 检查 Nginx 配置
cat /etc/nginx/conf.d/example.conf
# 测试配置
sudo nginx -t
# 重载配置
sudo systemctl reload nginx
# 查看 Nginx 错误日志
sudo tail -f /var/log/nginx/error.log
# 测试 WebSocket 连接
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://localhost:18789/
说明:文中域名、IP均为教学演示虚拟地址,无真实线上服务
最后更新:2026年7月9日CC BY-NC-SA 4.0
评论
暂无评论,来写第一条吧
