要让Nginx正确代理WebSocket,关键是完整透传HTTP升级握手过程:必须配置proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade",并调大proxy_read_timeout和proxy_send_timeout,禁用proxy_buffering。

要让 Nginx 正确代理 WebSocket 请求,关键不是“支持 WebSocket 协议”,而是**完整透传 HTTP 升级握手过程**。Nginx 本身不处理 WebSocket 帧,只负责把客户端的 Upgrade 请求原样转发给后端,并维持连接不中断。
必须配置的三行协议升级头
这三行缺一不可,共同构成 WebSocket 握手成功的前提:
-
proxy_http_version 1.1;:WebSocket 升级机制依赖 HTTP/1.1 的
Upgrade字段,HTTP/1.0 不支持。设为 1.0 或不设(默认可能为 1.0)会导致后端收不到升级意图。 -
proxy_set_header Upgrade $http_upgrade;:把客户端原始的
Upgrade头(如websocket、h2c等)原样传下去。写死成"websocket"会破坏非标准客户端(如某些嵌入式设备或自定义 SDK)的兼容性。 -
proxy_set_header Connection "upgrade";:注意是固定字符串
"upgrade",不是变量$connection。后者在多数情况下为空,Nginx 会自动补上Connection: close,直接导致握手失败或连接秒断。
超时参数必须同步调大
WebSocket 是长连接,空闲时不发数据是常态。Nginx 默认的 proxy_read_timeout 60s 会在 60 秒无数据时主动关闭连接,表现为客户端频繁重连或静默掉线。
-
proxy_read_timeout:设为业务最大空闲间隔的 2–3 倍。例如客户端每 30 秒发一次心跳,建议设为
90s或更高;聊天类应用可设为86400s(24 小时)。 -
proxy_send_timeout:影响后端向客户端推送大消息或分片数据的稳定性,需与
proxy_read_timeout同步调大,避免中途被切断。 - keepalive_timeout 不影响 WebSocket 连接:它控制的是客户端到 Nginx 的 HTTP 连接空闲超时,和后端 WebSocket 长连接无关,无需调整。
路径匹配与 location 设置要点
协议升级配置必须放在具体匹配 WebSocket 路径的 location 块中,不能只写在 server 或 http 全局块里:
- 典型路径如
/ws、/websocket、/api/ws或 MinIO 的/ws,需确保location的正则或前缀能精确命中。 - 如果后端要求 Host 头或协议标识(如判断是否为 HTTPS),还需补充:
proxy_set_header Host $host;proxy_set_header X-Forwarded-Proto $scheme; - 避免在该 location 中启用缓存或缓冲:
proxy_buffering off;(禁用响应缓冲,防止帧被暂存)tcp_nodelay on;(禁用 Nagle 算法,小包立即发送,降低实时延迟)
SSL 场景下 WSS 的额外注意点
当使用 wss://(即 Nginx 终止 HTTPS)时,后端常依赖请求头判断原始协议类型:
- 漏掉
X-Forwarded-Proto $scheme可能导致后端生成错误的http://回调链接,或拒绝安全连接。 - 若后端做基于域名的虚拟主机路由(如多租户 SaaS),
Host $host必须保留,否则路由失效。 - 证书配置本身不影响 WebSocket 升级逻辑,但 SSL 握手失败会阻断整个流程,需确保证书有效且域名匹配。


















