WebSocket握手卡顿主因是Nginx未正确透传Upgrade和Connection头,需配置proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade",并关闭缓冲、缓存及超时限制。

WebSocket 握手卡顿,多数不是网络问题,而是 Nginx 代理层没“听懂”客户端的升级请求。关键在于让 Nginx 正确透传、不干预、不缓冲,同时配合后端快速响应。
确保 Upgrade 和 Connection 头精准透传
这是握手成功的前提。Nginx 默认会过滤这两个 hop-by-hop 头部,必须显式放行:
- proxy_http_version 1.1:强制使用 HTTP/1.1,因 WebSocket 升级仅支持该版本
- proxy_set_header Upgrade $http_upgrade:用变量动态转发,避免写死成字符串(如 "websocket")导致匹配失败
- proxy_set_header Connection "upgrade":引号不可省略,且必须是小写 upgrade,否则后端可能拒绝识别
关闭缓冲与缓存机制
WebSocket 是流式协议,任何缓冲都会阻塞 101 响应,造成握手延迟甚至超时:
- proxy_buffering off:禁用响应体缓冲,确保 Upgrade 响应毫秒级透传
- proxy_cache off:防止 Nginx 将 Upgrade 请求误判为可缓存资源,返回 200 而非 101
- 避免启用 gzip 或其他响应重写模块,它们可能修改或截断握手响应头
延长连接空闲超时时间
握手完成后是长连接,但 Nginx 默认按短连接逻辑管理,60 秒就断开:
- proxy_read_timeout 86400:设为 24 小时(或略大于客户端心跳间隔),防止静默断连
- proxy_send_timeout 86400:保障服务端推送消息不因发送耗时被中断
- 注意:这些 timeout 作用于整个连接生命周期,不是单次请求;设为 0 在部分旧版 Nginx 中不可靠,建议用大整数
路径隔离与前置校验增强健壮性
用独立 location 匹配 WebSocket 流量,避免与其他路由冲突,并提前拦截非法请求:
- 使用明确路径如 location /ws { ... },而非兜底的 location /
- 添加校验:if ($http_upgrade != "websocket") { return 403; },拒绝非升级请求,减少后端无效负载
- 确保 proxy_pass 后端地址末尾无斜杠(如 http://backend:3000/ws 而非 /ws/),避免路径重写引发 404


















