要让nginx稳定代理websocket,关键是禁用默认http干扰行为:透传upgrade/connection头确保101握手成功,关闭proxy_buffering和proxy_cache防止帧延迟或粘包,启用tcp_nodelay并设proxy_read/send_timeout为86400秒以匹配心跳周期。

要让 Nginx 稳定代理 WebSocket 并做好连接状态维护与清理,关键不是“保活”而是“不干扰”——它不主动管理连接状态,而是通过禁用默认的 HTTP 行为,把长连接交还给业务层自主控制。
透传协议升级头,确保握手一次成功
WebSocket 连接始于 HTTP 升级请求,Nginx 若过滤或改写关键头部,后端收不到 Upgrade 信号,就会返回 200 而非 101,导致前端报错 “Unexpected response code: 200”。必须在对应 location 块中明确配置:
- proxy_http_version 1.1; —— HTTP/1.0 不支持 Upgrade,缺则握手直接失败
- proxy_set_header Upgrade $http_upgrade; —— 动态转发原始值(如 websocket、mqtt),避免硬编码失效
- proxy_set_header Connection "upgrade"; —— 注意英文双引号和字面量 upgrade,不能写成 $http_connection(可能含 keep-alive)
关闭缓冲与缓存,防止帧流被截断或延迟
WebSocket 是实时帧流协议,Nginx 默认启用的响应缓冲和缓存机制会破坏其低延迟特性:
- proxy_buffering off; —— 必须放在 location 块内,禁用缓冲可避免 TEXT/BINARY 帧堆积、粘包或乱序
- proxy_cache off; —— 显式关闭缓存,防止 Upgrade 请求被缓存命中返回 200
- tcp_nodelay on; —— 绕过 Nagle 算法,小帧(如心跳、聊天消息)立即送达,不等待合并
超时设置远大于心跳周期,避免静默断连
WebSocket 空闲时依赖后端 ping/pong 维持活跃,Nginx 默认 60 秒超时会误判为“僵死连接”并主动关闭:
- proxy_read_timeout 86400; —— 设为 24 小时,覆盖任意心跳间隔(例如后端每 30 秒发 pong,此处至少设 60 秒以上)
- proxy_send_timeout 86400; —— 防止向后端推送大数据分片或慢响应时被中断
- keepalive_timeout 86400; —— 保持客户端到 Nginx 的连接存活,与上游超时对齐更稳妥
路径匹配精准 + 后端健康协同,保障请求真正落地
配置再正确,若请求没进对的 location,一切无效:
- 使用 = /ws(精确匹配)或 /ws/(前缀匹配),避免 rewrite 改写路径或 header
- 若用 upstream,建议加 keepalive 32; 复用到后端的空闲连接,并配 max_fails=1 fail_timeout=10s 做基础探活
- HTTPS 场景下,必须启用 TLSv1.2+,且 proxy_http_version 1.1 仍需保留(HTTP/2 不支持 Upgrade)











