在 nginx 中配置 websocket 代理,核心在于正确传递 http 升级请求头并维持长连接。你需要修改 `location` 块中的 `proxy_pass` 指令,同时必须设置 `upgrade` 和 `connection` 两个关键头部变量,以确保后端服务能识别协议切换请求。

如何配置 Upgrade 和 Connection 头部
要实现 WebSocket 握手,Nginx 必须将客户端发来的 `Upgrade: websocket` 和 `Connection: Upgrade` 原样传递给后端服务器。这通过 `proxy_set_header` 指令配合 Nginx 内置变量 `$http_upgrade` 和 `$connection_upgrade` 来实现。如果缺少这些配置,Nginx 会将其视为普通 HTTP 请求,导致连接被立即关闭或返回 400/502 错误。

server {
listen 80;
server_name example.com;
location /ws/ {
proxy_pass http://backend_server;
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_http_version 1.1` 是必须的,因为 WebSocket 协议基于 HTTP/1.1。`$http_upgrade` 变量在客户端发送 Upgrade 头时值为 "websocket",否则为空;`$connection_upgrade` 通常设为 "upgrade" 或 "keep-alive"。当两者结合时,Nginx 仅在需要升级时发送 Upgrade 头,其他时间保持 Keep-Alive,这是标准做法。
如何处理超时与长连接保持
WebSocket 连接是持久的,默认情况下 Nginx 的 `proxy_read_timeout` 和 `proxy_send_timeout` 可能会在空闲一段时间后切断连接。为了防止这种情况,你需要针对 WebSocket 路径单独设置较长的超时时间,或者禁用超时检查。此外,还需注意 `proxy_buffering` 的设置,确保数据流不被缓冲阻塞。

location /ws/ {
proxy_pass http://backend_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 关键:防止 Nginx 过早断开空闲连接
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
# 关键:禁用缓冲,确保实时数据传输
proxy_buffering off;
}
在实际部署中,`proxy_read_timeout` 设置为 86400 秒(一天)可以极大减少因网络波动导致的意外断连。`proxy_buffering off` 告诉 Nginx 不要等待后端响应完毕再发送给客户端,这对于即时通讯类应用至关重要。若后端服务本身有健康检查机制,建议在后端层面处理心跳包,而非依赖 Nginx 的超时策略。
基于特定路径前缀的代理行为差异
当 Nginx 配置了多个 location 块时,WebSocket 路径 `/ws/` 与普通 API 路径 `/api/` 的处理逻辑截然不同。普通 API 通常使用短连接,而 WebSocket 需要长连接。如果错误地将 WebSocket 流量路由到未配置 Upgrade 头的 location,或者反之,会导致协议不匹配。例如,访问 `/ws/` 时,Nginx 会建立 TCP 长连接并维持状态;而访问 `/api/` 时,Nginx 会完成一次请求后关闭连接。这种差异要求我们在配置时必须严格区分路径,并确保每个路径对应的 proxy 参数符合其通信模式。











