Nginx 反向代理普通 HTTP 请求时,配置通常很快就能跑起来;换成 WebSocket 后,页面能打开,但连接一会儿就断,或者后端一直收到 400。这类问题多数和升级连接头没有正确传递有关。
先确认后端确实提供 WebSocket
先绕过 Nginx,从内网直接访问后端。确认后端端口、路径和协议都正确,再开始改代理配置。浏览器开发者工具的 Network 面板里,如果握手失败,通常能看到具体的状态码。
配置升级连接
一个常用的 Nginx 配置如下:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name example.com;
location /socket/ {
proxy_pass http://127.0.0.1:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 60s;
}
}
WebSocket 连接需要 HTTP/1.1 和 Upgrade、Connection 相关请求头。map 放在 http 配置块中,location 中再引用变量。
检查配置是否真正生效
sudo nginx -t
sudo nginx -T | less
sudo systemctl reload nginx
nginx -t 只检查语法;要确认实际加载的配置,应查看 nginx -T 的完整结果。特别注意是否还有另一个 server 块抢先匹配了域名,以及 location 路径是否和前端使用的 WebSocket URL 一致。
排查 400、404 和 502
返回 400 时,先看后端要求的路径、Origin 和鉴权信息。返回 404 时,通常是 location 没匹配到,或者 proxy_pass 末尾的斜杠改变了后端收到的路径。返回 502 时,检查后端是否监听在 Nginx 所在机器能访问的地址:
ss -ltnp | grep 9000
curl -i http://127.0.0.1:9000/health
sudo tail -f /var/log/nginx/error.log
如果后端只监听 127.0.0.1,而 Nginx 在另一个容器中,容器里的 127.0.0.1 指向 Nginx 自己,不是后端容器。此时应使用 Docker 服务名或同一网络中的地址。
连接容易断开时看超时
WebSocket 是长连接。如果后端很久没有数据,而 Nginx 的读取超时过短,连接就会被关闭。可以适当调整 proxy_read_timeout,但不要把它当成所有断连问题的答案。还要检查后端是否需要定时发送 ping,以及负载均衡或 CDN 是否有自己的连接时长限制。
上线前做一次浏览器验证
重新加载 Nginx 后,打开浏览器开发者工具,确认握手返回 101 Switching Protocols,并观察连接保持时间。普通页面能打开,只能说明 HTTP 代理正常,不能证明 WebSocket 已经配置成功。
这类问题排查时,先验证后端,再看 Nginx 最终配置,最后检查浏览器握手和超时。不要只复制一段配置就反复 reload,日志里的状态码通常比猜配置更快给出方向。


暂无评论内容