核心是缓冲区与超时协同失配,需同步调整proxy_buffer_size、proxy_busy_buffers_size和proxy_send_timeout,并优化后端Header大小与流式响应节奏。

核心是缓冲区与超时协同失配,不是单点调大就能解决。重点在 proxy_buffer_size、proxy_busy_buffers_size 和 proxy_send_timeout 三者咬合,同时避免后端 Header 膨胀和流式节奏不稳。
先确认是不是响应头真太大
错误日志里出现 upstream sent too big header while reading response header from upstream,说明问题出在响应头阶段:
- 用
curl -v http://your-api/endpoint 2>&1 | grep '^<' | wc -c查原始响应头总字节数(含状态行和 CRLF) - 对比当前
proxy_buffer_size值(默认常为 4k 或 8k);若实测值接近或超过,就是它卡住的 - 检查后端是否重复设
Set-Cookie、注入X-Debug-Info、塞了未压缩的长 JWT,或网关层层叠加 Header
精准调大 proxy_buffer_size 并配套 buffer 设置
proxy_buffer_size 只管响应头,必须完整读完才能拿到状态码和传输控制信息:
- 按实测 Header 字节数向上取最接近的 2 的幂次:测出 5212 字节 → 设为
6k或8k;测出 28KB → 设为32k - 写在对应
location块内,且必须出现在proxy_pass之前 - 同步协调
proxy_buffers和proxy_busy_buffers_size:例如设了proxy_buffer_size 32k,推荐搭配proxy_buffers 8 16k(共 128k)和proxy_busy_buffers_size 64k - 若用 HTTP/2,额外检查
http2_max_field_size(默认 4k),它独立限制单个 Header 字段长度
防止大响应体传输中断的关键是 busy_buffers_size + send_timeout
后端已开始返回大量数据(如导出 Excel、SSR HTML、分块日志),但 Nginx 却“停着不收”,本质是忙缓冲区满导致 TCP 窗口收缩:
- 确认
proxy_buffering on已启用(默认是 on,但 location 内可能被覆盖) -
proxy_busy_buffers_size应为proxy_buffers总量的 1/4~1/2,且 ≥ 单块大小:比如proxy_buffers 16 256k(共 4MB),则proxy_busy_buffers_size至少设为1m -
proxy_send_timeout控制两次数据包间隔,不是总耗时;后端每 30 秒 flush 一次,就设为45s;SSE 或分块下载建议300s - 务必确保
proxy_read_timeout≥proxy_send_timeout,否则还没传几块就被整体掐断
长期更优解:从源头压减响应头和优化流式节奏
调大缓冲只是兜底,高可用场景下应减少对 Nginx 缓冲的依赖:
- 后端移除调试类 Header、合并重复 Cookie、压缩或缩短 Token
- 将元数据从 Header 搬到响应体,或通过查询参数传递
- 对纯流式接口(如日志 tail、SSE),直接关闭 buffering:
proxy_buffering off,靠proxy_buffer_size控制头,body 直通 - 后端代码确保
flush()及时(如 Spring Boot 的ResponseEntity<StreamingResponseBody>,Netty 的writeAndFlush())


















