必须禁用Nginx缓存与压缩:proxy_cache off、proxy_buffering off、禁用gzip;仅启用tcp_nodelay、延长proxy_read_timeout/proxy_send_timeout,并严格隔离静态资源的缓存配置。

WebSocket 是长连接、全双工通信协议,本身不适用传统 HTTP 缓存机制,也不该启用响应压缩(如 gzip)。所谓“为 WebSocket 配置缓存与压缩策略”,核心不是开启它们,而是明确禁用干扰项,并在传输层做轻量级优化——否则极易导致握手失败、消息延迟、帧粘包或连接静默中断。
必须禁用的缓存相关配置
WebSocket 握手请求(Upgrade: websocket)若被 Nginx 缓存,后端将收不到升级信号,直接返回 200 而非 101,前端报错 “Unexpected response code: 200”。因此:
-
proxy_cache off;
显式关闭缓存,防止 Upgrade 请求或空闲帧被误存 -
proxy_cache_bypass $http_upgrade;
作为兜底:只要请求头含Upgrade,就跳过缓存检查 -
proxy_buffering off;
关键!避免 Nginx 把后端推送的帧攒满缓冲区再发,造成毫秒级消息卡顿数秒 - 删除所有
proxy_cache_path、proxy_cache_valid等缓存指令
WebSocket 场景下这些配置不仅无用,反而增加内存开销和出错概率
不该对 WebSocket 做内容压缩
-
不要在
location /ws { ... }块中启用gzip on;或gunzip on;
WebSocket 帧是二进制或文本载荷,由客户端/服务端自行协商并启用permessage-deflate扩展(RFC 7692)。Nginx 对已升级连接不做 payload 解析,强行 gzip 会破坏帧结构,导致解码失败。 - 若需压缩,应在 WebSocket 协议层开启:
- 客户端(浏览器)自动支持
permessage-deflate(无需额外配置) - 后端框架(如 Spring WebFlux、Netty、Socket.IO)需显式启用该扩展
- Nginx 无需参与,也不应干预
- 客户端(浏览器)自动支持
可选但推荐的轻量级传输优化
仅作用于已成功升级的 TCP 连接,不影响协议逻辑:
-
tcp_nodelay on;
关闭 Nagle 算法,避免小帧(如心跳、状态更新)被合并延迟发送。注意:它只对 upgrade 后的连接生效 -
proxy_read_timeout 86400;和proxy_send_timeout 86400;
防止空闲连接被超时关闭,确保心跳周期稳定(建议设为略大于客户端心跳间隔,如心跳 30s,则设 45s~300s) -
proxy_buffer_size 16k;与proxy_buffers 8 16k;
仅用于暂存握手响应头及少量初始帧,避免因缓冲太小导致截断;不是为了缓存消息流
静态资源可独立启用缓存与压缩
WebSocket 代理路径(如 /ws、/api/ws)之外的静态资源(JS/CSS/图片等),仍可正常配置:
-
gzip on;+gzip_types application/javascript text/css image/svg+xml; -
proxy_cache+proxy_cache_valid用于 API 查询类接口(非 WebSocket) - 但必须严格隔离:这些指令不能出现在 WebSocket 的 location 块内
不复杂但容易忽略——WebSocket 的“优化”本质是卸掉默认配置的包袱,而非叠加功能。


















