在 nginx 中代理 websocket 长连接时,必须显式配置 `proxy_read_timeout`、`proxy_send_timeout` 和 `proxy_connect_timeout`,并将它们设置为较大的值(如 86400s),同时配合 `upgrade` 和 `connection` 头部的透传。默认情况下 nginx 的超时时间较短(通常 60s),会导致空闲连接被切断。通过修改这些参数,可以确保 websocket 连接在长时间无数据交互时依然保持活跃。

如何配置 Nginx 以支持 WebSocket 升级握手
要实现 WebSocket 代理,核心是正确转发 HTTP 升级请求。需要在 `location` 块中设置 `proxy_http_version 1.1;`,并添加 `proxy_set_header Upgrade $http_upgrade;` 和 `proxy_set_header Connection "upgrade";`。这告诉 Nginx 将客户端的升级请求原样传递给后端服务,从而建立 WebSocket 通道。

server {
listen 80;
server_name ws.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_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 60s;
}
}
为什么默认超时会导致连接断开以及如何验证
Nginx 默认的 `proxy_read_timeout` 为 60 秒。如果 WebSocket 连接在 60 秒内没有收到任何数据,Nginx 会主动关闭连接。为了验证这一点,可以使用 curl 或简单的 Python 脚本模拟一个长时间空闲的连接。如果不设置长超时,连接会在一段时间后报错或断开。通过上述配置,我们将超时时间延长至一天(86400秒),足以覆盖绝大多数业务场景的空闲间隔。

# 使用 curl 测试 WebSocket 连接(需安装 wscat 或使用类似工具) # 这里展示一个简单的 nginx.conf 片段用于验证超时行为 # 在 backend 端,我们可以写一个简单的 echo 服务 # 但主要验证点在于 Nginx 侧的配置 # 验证命令示例(假设后端已启动): wscat -c ws://localhost/ws/ # 保持连接超过 60 秒,若未断开则说明配置生效
基于 proxy_read_timeout 参数的具体影响分析
在上面的配置中,`proxy_read_timeout` 决定了 Nginx 等待后端服务器发送响应的最长时间。对于 WebSocket,这个“响应”就是持续的数据流。如果设置为 0,表示禁用超时,连接将永久保持直到客户端或服务器断开。但在生产环境中,建议设置一个合理的极大值而非 0,以防止因后端故障导致的资源无限占用。结合 `proxy_send_timeout`,可以确保双向通信的稳定性。此外,`proxy_connect_timeout` 仅影响初始 TCP 连接的建立,对已建立的 WebSocket 数据通道无直接影响,因此通常保持默认或较短时间即可。


















