Nginx反向代理websocket完整配置

Nginx 反向代理 WebSocket 时,如果只按普通 HTTP 代理配置,客户端连接很快会断开,或者直接返回 400、502 等错误。
核心原因有两个:Nginx 默认不会向 WebSocket 服务传递 Upgrade 和 Connection 头,同时 proxy_read_timeout 默认只有 60 秒,长连接一旦超过这个时间就会被 Nginx 切断。
本文给出可直接落地的完整配置,同时解决 ws/wss 反向代理和连接超时问题,适合尚未配置过 WebSocket 代理的新手运维参考。

准备工作:确认环境与源服务

先确认三件事:

  1. Nginx 版本:1.3 及以上版本才支持 WebSocket 反向代理,建议使用 1.18 或更新版本。执行 nginx -v 查看。
  2. WebSocket 源服务地址:例如本地服务监听 127.0.0.1:8080,路径为 /ws
  3. 域名和证书:如果希望浏览器通过 wss:// 访问,需要提前配置 SSL 证书;只在内网测试可用 ws://

确认后,先备份原配置:cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

核心配置:普通 ws 反向代理

进入 Nginx 站点配置目录(如 /etc/nginx/conf.d/),新建一个配置文件或修改现有站点配置。
下面是一段最基础的 ws 反向代理配置:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 80;
    server_name example.com;

    location /ws {
        proxy_pass http://127.0.0.1:8080;
        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 3600s;
        proxy_send_timeout 3600s;
    }
}

关键点说明:

  • proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade; 是让 Nginx 正确转发 WebSocket 握手升级的必备条件
  • map 块需要放在 http 上下文中,如果写在 server 里会报错。
  • 超时时间proxy_read_timeout 控制从后端服务读取数据的等待时间,WebSocket 长连接建议设置为 3600s,否则连接会在 60 秒后被动断开。同理也设置 proxy_send_timeout

配置完成后测试语法并重载:

nginx -t
systemctl reload nginx

如果 nginx -t 通过,说明配置格式正确。

升级为 wss:让加密 WebSocket 生效

当浏览器需要访问 wss://example.com/ws 时,Nginx 负责终止 TLS 加密,再以普通 ws:// 转发给后端。
只需要在原 server 上添加 SSL 监听,或新建一个 443 端口 server 块:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.crt;
    ssl_certificate_key /etc/nginx/ssl/example.key;

    location /ws {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

需要留意:后端服务不变,仍然是 ws://,不要改成 proxy_pass https://,否则后端不认 TLS 就会握手失败。
证书路径根据你实际部署位置修改。

避坑:连接超时和不稳定的常见原因

实际使用中,不少连接问题不是 Nginx 配置写错,而是下面几个细节被忽略:

  • 忘记配置 proxy_set_header Upgrade:最常见的 400 Bad Request 或 502 错误来源。可用 curl -v -H "Connection: Upgrade" -H "Upgrade: websocket" http://127.0.0.1:8080/ws 测试后端是否正常。
  • proxy_read_timeout 太小:业务允许长连接时,如果一直周期性断开,先检查这里的值。日志中会出现 upstream timed out 的提示。
  • 多个 location 共用超时配置:如果项目里还有 API 接口,建议把 WebSocket 路径单独拆分出来,避免把上传文件接口的超时时间也拉到 3600 秒。
  • 负载均衡多台后端:WebSocket 长连接必须绑定固定后端,否则握手成功后请求被转发到不维护连接的另一台机器。可使用 ip_hashsticky 模块,保证同一客户端始终访问同一后端。

验证配置是否真正生效

nginx -t 通过并不代表 WebSocket 代理成功,还需要实际连接测试。

  1. 使用浏览器开发者工具:打开 Console,执行
var ws = new WebSocket("ws://example.com/ws");
ws.onopen = function(){ console.log("connected"); };
ws.onclose = function(e){ console.log("closed", e.code, e.reason); };
  1. 使用命令行工具 wscat(Node 环境):
npm install -g wscat
wscat -c ws://example.com/ws

如果能正常收到 connected,说明代理成功。
然后把服务保持连接超过 60 秒,观察是否会断开;
若仍断开,重新检查 proxy_read_timeoutproxy_send_timeout 是否已加载。

  1. 查看 Nginx 错误日志:默认在 /var/log/nginx/error.log,出现 upstream timed out 时优先检查超时配置;出现 no live upstreams 时检查后端 WebSocket 服务是否存活。

完成以上步骤后,ws/wss 反向代理和连接超时问题基本都能解决。
如果之后遇到更复杂的场景,比如多站点共用 Nginx 或 TLS 证书更新,可以继续查阅本站其他运维教程。

分享到:
上一篇
MySQL数据库锁等待超时,show
下一篇
Nginx访问日志中真实客户端IP获取
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意