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 配置?

  1. 错误信息是 WebSocket connection failed,说明 WebSocket 握手失败
  2. WebSocket 和普通 HTTP 请求不同,需要特殊的头信息
  3. Nginx 作为反向代理,如果不配置 WebSocket 支持,会拦截 WebSocket 请求
  4. 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 请求,需要通过 UpgradeConnection 头告诉它。


七、经验总结

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 问题的思路

  1. 检查服务端是否正常运行
  2. 检查 Nginx 是否支持 WebSocket(关键配置是否完整)
  3. 检查 SSL 证书是否有效
  4. 检查客户端是否有代理/网络问题

八、附录:相关命令

# 检查 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

评论

暂无评论,来写第一条吧

© 2026 My Blog. Built with Nuxt.js + FastAPI.