WebSocket大文本被Nginx截断的根源是proxy_buffering开启导致帧被缓存分块,解决需关闭proxy_buffering、透传Upgrade/Connection头、调优超时并由后端分帧处理。

WebSocket传输超大文本被Nginx缓冲区截断,本质不是“传输失败”,而是Nginx在代理过程中误将WebSocket帧当作HTTP响应体处理,启用了默认缓冲机制,导致大JSON或长消息被分块缓存、延迟推送,甚至因内存限制被静默丢弃。解决关键在于关闭缓冲、透传协议、隔离传输逻辑,而非调大buffer_size。
必须关闭proxy_buffering并禁用相关干扰项
Nginx默认开启proxy_buffering,会把后端发来的WebSocket帧暂存到内存缓冲区,等攒够再发给客户端——这对HTTP有效,对WebSocket却是灾难:帧边界错乱、心跳延迟、大文本被截断或OOM崩溃。
- 在对应WebSocket的
location块中强制关闭:proxy_buffering off; - 同步禁用gzip压缩:
gzip off;(否则压缩可能破坏二进制帧完整性) - 不要设置
proxy_buffers、proxy_buffer_size等参数——它们对WebSocket无效且易引发混淆
确保协议升级头完整透传
若Upgrade/Connection头被Nginx过滤或改写,后端无法完成握手,后续所有数据(无论大小)都会被当作普通HTTP响应处理,自然落入缓冲区逻辑。
- 必须包含三行(缺一不可):
proxy_http_version 1.1;<br>proxy_set_header Upgrade $http_upgrade;<br>proxy_set_header Connection "upgrade";
- 检查Nginx配置中是否在该location内意外覆盖了
proxy_set_header Connection(例如设为close或keep-alive) - 避免在该location中使用
proxy_cache、proxy_redirect、proxy_intercept_errors等与长连接冲突的指令
超时设置要匹配实际业务空闲周期
proxy_read_timeout控制Nginx等待后端数据的时间。若设为默认60秒,空闲期间无消息就会断连,触发重连后大文本重传,看起来像“截断”。
- 设为业务最长空闲时间,建议至少
proxy_read_timeout 3600;(1小时) - 配套设置
proxy_send_timeout 3600;,防止大文本发送中途被中断 - 注意:该值不是越大越好,需小于中间网络设备(如云LB、防火墙)的空闲超时(通常30–90秒),因此前端仍需按25秒节奏主动ping
大文本本身应由后端分帧,而非依赖Nginx调整
Nginx不解析WebSocket帧内容,也不限制单帧大小。真正卡住大文本的是后端服务(如Tomcat的textBufferSize)和浏览器解析能力。
- SpringBoot+Tomcat需显式调大缓冲:
@Bean public WebServerFactoryCustomizerwebServerFactoryCustomizer() { return factory -> factory.addAdditionalTomcatConnectors(...).setMaxSwallowSize(-1); } - 浏览器对单帧有隐式限制(通常≤4MB),超过建议后端拆成多帧发送,或改用“分块上传+WebSocket通知”模式
-
client_max_body_size对WebSocket无效(不走HTTP body),无需修改











