要实现大文件流式转发,必须关闭proxy_request_buffering并协同配置client_max_body_size(设于server块)、超时参数、proxy_buffering off及HTTP/1.1长连接,后端还需适配原始字节流读取。

要让 Nginx 实现大文件上传的流式转发,关键不是“加速传输”,而是让请求体边接收、边转发给后端,避免全量缓存导致卡顿、超时或内存溢出。单改一个参数基本无效,必须多项配置协同生效。
必须关闭 proxy_request_buffering
这是最核心也最容易被忽略的一步。Nginx 默认开启该功能,会把整个上传文件(比如 2GB 视频)先收完、缓存到内存或临时磁盘,再发给后端——结果就是上传进度卡在 99%,首字节延迟高,worker 内存暴涨甚至 OOM。
- 仅在需要上传的 location 块中设置:
proxy_request_buffering off; - 不能写在 http 或 server 层,否则会影响所有接口
- 关闭后,Nginx 不再解析 multipart boundary,也不校验 body,直接 TCP 层转发原始字节流
client_max_body_size 要设对位置和单位
它决定请求能否进入 Nginx 处理流程,是第一道门槛。设错位置或格式,大文件请求根本不会走到 proxy_pass,直接返回 413 错误。
- 必须写在
server或http块中,不能放在 location 里 - 建议值如
client_max_body_size 20G;或2048m;注意单位大小写敏感,2G无效 - 同时需同步调整后端限制,例如 Spring Boot 的
max-file-size、Flask 的MAX_CONTENT_LENGTH
配套调大超时与禁用响应缓冲
关闭 request buffering 后,数据流变长且不可预测,原有默认超时极易中断上传。同时,后端返回的上传状态、分块确认等响应也需实时透传,不能被缓存阻塞。
-
client_body_timeout 3600;:允许弱网下分多次传完一个大文件 -
proxy_read_timeout 3600;和proxy_send_timeout 3600;:匹配后端处理耗时(如校验、转码、落盘) -
proxy_buffering off;:确保响应也能流式返回,避免进度回调被延迟 -
proxy_http_version 1.1;+proxy_set_header Connection '';:维持长连接,防中间设备断连
后端必须能消费原始流式请求体
Nginx 不缓存、不解析 body,意味着上传数据以原始字节流形式抵达后端。常见框架需显式启用流式读取,不能依赖默认的 multipart 解析。
- Node.js(Express):禁用
body-parser,改用busboy监听req.on('data') - Python(FastAPI/Flask):不调用
request.files,改用request.stream分块读取 - Go(net/http):直接读
req.Body,用io.Copy或分片io.ReadFull处理


















