proxy_read_timeout 应按后端p99数据块间隔加缓冲设定,如38秒加5–10秒设为45秒;须同步调大proxy_send_timeout、send_timeout,并启用keepalive、proxy_buffering off及chunked_transfer_encoding。

proxy_read_timeout 要延长,不能只改一个数字,得结合大文件下载的实际节奏来设——它管的不是“整个下载耗时”,而是后端返回响应头之后,两次数据块到达之间允许的最大空闲时间。
明确它真正起作用的阶段
当用户点击下载,后端开始处理(查库、生成文件、分块写入),Nginx 在收到第一个响应头(如 HTTP/1.1 200 OK 和 Content-Disposition)后,才启动 proxy_read_timeout 计时器。此后只要后端每过一段时间就发一点数据(比如每 5–30 秒 flush 一次),Nginx 就会重置计时;一旦停顿超时,立刻断连报 504。
- 它不管后端花 2 分钟才返回响应头(那是 proxy_connect_timeout 或后端自身问题)
- 也不管客户端网速慢、下载卡顿(那是 send_timeout 的职责)
- 更不控制 Nginx 自己发请求体有多慢(那是 proxy_send_timeout)
按真实流式节奏设值,别拍脑袋填 3600
先查后端导出接口的监控数据,重点看 P99 的“两次数据块间隔”(不是总耗时)。例如:
- 日志或 APM 显示:后端平均每 22 秒 flush 一次,P99 是 38 秒
- 加 5–10 秒缓冲(应对 GC 暂停、DB 延迟、网络抖动)
- 推荐设为 45 秒,比盲目填 300 或 3600 更精准、更节省连接资源
必须同步调这三项,单改无效
proxy_read_timeout 只是链条中一环,以下参数必须同频放大:
- proxy_send_timeout ≥ proxy_read_timeout:防止带大筛选条件的 POST 请求还没发完就被切断
- send_timeout ≥ proxy_read_timeout:确保弱网用户下载时,Nginx 不因客户端接收慢而提前断连
- upstream 开启 keepalive 并配 proxy_http_version 1.1:避免每次下载都新建 TCP 连接,否则 TIME_WAIT 爆满,再长的 timeout 也没用
配合流式响应的关键开关
对 Excel、CSV、PDF 等边生成边传输的场景:
- proxy_buffering off;:关掉 Nginx 缓存整块响应的行为,避免“等不到完整响应就不发”,造成假超时
- 可加 chunked_transfer_encoding on;:支持分块传输,提升兼容性
- 后端超时建议设为 Nginx 值的 0.8 倍(如 proxy_read_timeout=45,则 Tomcat connectionTimeout 设为 36),错开超时点,避免互相甩锅











