要精准定位 websocket 握手失败,必须将 nginx error_log 调至 debug 或 info 级别以暴露 upgrade 头透传、http/1.1 版本设置及上游 101 响应等关键协议行为,配合自定义 access_log 记录请求与响应头,并紧盯 debug 日志中 http 版本降级、头字段丢弃、上游响应异常三类线索。

要真正用好 Nginx 的 error_log 定位 WebSocket 连接异常,关键不是盲目开 debug,而是让日志精准暴露握手阶段的协议行为——比如 Upgrade 头有没有传过去、HTTP 版本是否降级、上游有没有返回 101。
把 error_log 调到 info 或 debug 级别才看得见握手细节
默认的 error 级别只会记 502/504 这类结果错误,但 WebSocket 握手失败往往发生在更早环节,比如头被丢弃、协议不匹配。必须主动提级:
- 临时排查时,在对应
server或location块里加:error_log /var/log/nginx/ws_debug.log debug; - 若只想要关键警告(如证书过期、重定向循环、上游拒绝),
warn级已足够,且不影响性能 - 确认 Nginx 编译时启用了
--with-debug,否则 debug 日志不会输出 - 改完后必须
nginx -t && nginx -s reload,否则配置不生效
结合 access_log 显式记录 Upgrade 和 Connection 头
debug 日志太长难筛选,access_log 可以快速比对客户端发了什么、后端收到了什么:
- 定义日志格式:
log_format ws_debug '$remote_addr - $remote_user [$time_local] "$request" $status "$http_upgrade" "$http_connection" "$upstream_http_upgrade" "$upstream_http_connection";' - 在 WebSocket 对应的
location中启用:access_log /var/log/nginx/ws_handshake.log ws_debug; - 成功握手时:
$http_upgrade和$upstream_http_upgrade都应为websocket;若前者有值后者为空,说明proxy_set_header Upgrade $http_upgrade没生效
紧盯 debug 日志里的三类关键线索
开启 debug 后,不用通读全文,直接搜索这几类提示:
-
HTTP 版本降级:出现
using HTTP/1.0 to backend,说明proxy_http_version 1.1未生效,握手必然失败 -
头字段丢弃:如
discarding header 'Upgrade'或header 'Connection' not passed,直指proxy_set_header配置缺失或拼写错误 -
上游响应异常:如
upstream sent no valid HTTP/1.0 header,配合前两点可判断是后端因头缺失拒绝,还是网络中断导致无响应
别忽略系统级日志和命令交叉验证
仅看 Nginx 日志容易误判,遇到典型报错要立刻联动检查:
- 报
bind() to 0.0.0.0:443 failed (98: Address already in use)→ 执行ss -tulnp | grep :443查端口占用 - 前端显示
net::ERR_CONNECTION_REFUSED→ 先用curl -v https://yourdomain.com测 HTTPS 是否通,再加头测握手:curl -v -H "Connection: upgrade" -H "Upgrade: websocket" https://yourdomain.com/ws - 怀疑防火墙或云安全组拦截 → 确认 443(或自定义 wss 端口)已放行,不只是后端应用端口(如 8080)











