WebSocket握手延迟高主因是Nginx代理未适配协议特性,需显式透传Upgrade头、关闭缓冲与压缩、设长超时并验证101响应。

WebSocket 握手延迟高,通常不是因为 Nginx 本身慢,而是代理配置未适配 WebSocket 协议特性。关键在于让 Nginx 正确透传 Upgrade 请求、维持长连接,并避免缓冲和超时干扰。
确保启用必要的 HTTP 升级头字段
WebSocket 握手依赖 Connection: Upgrade 和 Upgrade: websocket 这两个请求头,Nginx 默认不转发非标准头,必须显式开启透传:
- 在 location 块中添加:
proxy_set_header Connection 'upgrade'; - 同时设置:
proxy_set_header Upgrade $http_upgrade; - 注意:
$http_upgrade是 Nginx 内置变量,会自动提取客户端的 Upgrade 头值(如websocket),不能写死为字符串
关闭响应体缓冲与压缩
握手阶段是纯 HTTP 101 响应,无响应体,但若启用 proxy_buffering on 或 gzip on,Nginx 可能等待缓冲或压缩判断,引入毫秒级延迟:
- 明确关闭:
proxy_buffering off; - 禁用 gzip(尤其对 101 响应无效且可能触发额外处理):
gzip off;或在该 location 中用gzip_disable "msie6";配合更细粒度控制 - 避免使用
proxy_http_version 1.0,始终用1.1
调优连接保活与超时参数
握手完成后连接进入长连接状态,但若上游或 Nginx 过早中断,会导致重连和重复握手。需同步调整三处超时:
-
proxy_read_timeout 86400;(推荐设为较大值,如一天,表示空闲时保持连接不关闭) -
proxy_send_timeout 86400;(同上,覆盖发送侧空闲超时) -
keepalive_timeout 75s;(客户端到 Nginx 的 TCP keepalive,建议 ≥ proxy_read_timeout 的 1/3) - 上游服务(如 Node.js/Python)也需匹配类似长超时,否则 Nginx 等待期间上游先断开,触发重试或失败
验证是否真正透传而非降级为轮询
延迟高有时源于握手实际失败,Nginx 返回了 200 而非 101,前端被迫回退到 HTTP 轮询:
- 用浏览器开发者工具 → Network 标签,筛选 WS,检查状态码是否为 101 Switching Protocols
- 查看 Response Headers 是否含
Connection: upgrade和Upgrade: websocket - 抓包验证:若看到
HTTP/1.1 200 OK后续又发新请求,说明代理未生效,需检查 upstream 是否拒绝 Upgrade 或 Nginx 配置未生效


















