关闭 proxy_request_buffering 是实现大文件流式上传的前提,需同步调大 client_max_body_size、延长超时、关闭 proxy_buffering、启用 HTTP/1.1 并确保后端支持流式解析 multipart 请求体。

关闭 proxy_request_buffering 是 Nginx 实现大文件上传流式转发的关键一步,但仅设为 off 并不自动完成流式转发——它只是让 Nginx 不缓存客户端请求体,把原始 TCP 数据流边收边转给上游。真正实现可靠的大文件流式上传,还需配合超时、缓冲区、HTTP 版本、上游协议等一整套配置协同工作。
为什么必须关掉 proxy_request_buffering?
Nginx 默认开启 proxy_request_buffering on,意味着它会把整个上传请求(包括大文件)先完整接收并暂存在内存或临时文件中,校验完请求头、重写规则、鉴权等逻辑后,再一次性转发给后端。这对小请求友好,但对 GB 级上传会导致:
- 高内存/磁盘占用,可能触发 OOM 或写满临时目录
- 客户端感知“卡住”:上传进度停滞在 99%,直到 Nginx 缓存完成才开始发往后端
- 无法实时透传上传进度,后端无法做分块校验、实时预处理等
设为 off 后,Nginx 变成“管道模式”:收到一点数据就立刻尝试转发一点,不等待完整 body,也不做校验(如 multipart boundary 检查),因此要求后端能正确解析流式到达的原始 HTTP 请求体。
核心配置项必须同步调整
单独关 buffering 不够,以下参数需配套优化,否则易出现连接中断、截断、502 等问题:
-
client_max_body_size:设为足够大(如
0表示不限制),避免 Nginx 在 buffering 关闭时仍因大小拦截 -
client_body_timeout 和 proxy_send_timeout:延长超时(如
600s),防止慢速上传或网络抖动导致连接被关 - proxy_buffering off:同时关闭响应缓冲,确保后端返回的响应(如上传状态、分块确认)也能流式透传回客户端
- proxy_http_version 1.1:启用 HTTP/1.1,支持 chunked transfer encoding,适配流式 body 分段转发
- proxy_set_header Connection '':清除 Connection 头,避免 upstream 错误关闭 keepalive 连接
后端服务需适配流式请求体
Nginx 不缓存、不解析 body,意味着上传数据以原始字节流形式抵达后端。常见框架需显式启用流式解析:
-
Node.js(Express):禁用
body-parser的默认 multipart 解析,改用busboy或formidable监听req的data事件 -
Python(FastAPI / Flask):不调用
request.files或request.form,而是读取request.stream进行分块处理 -
Go(net/http):直接读
req.Body,用io.Copy或分片io.ReadFull处理,不依赖ParseMultipartForm
特别注意:multipart boundary 若被 Nginx 分割在两个 TCP 包中,而你的后端未做 buffer 合并,可能导致解析失败——建议后端使用成熟流式 multipart 库(如 node-formidable 的 encoding: 'binary' 模式)。
实测验证与排错要点
上线前务必用真实大文件 + 断点续传场景验证:
- 用
curl -v -F "file=@large.zip" http://your.domain/upload观察 Nginx access log 是否实时打印(非等上传完才写) - 抓包(tcpdump 或 Wireshark)确认 client → nginx → upstream 三段流量是否连续、无长时间 gap
- 检查 Nginx error log 中是否出现
upstream prematurely closed connection—— 多因 upstream 超时或主动断连,需调大后端 read timeout - 若上传中途失败,确认 client 是否发送了
Connection: close或 FIN,Nginx 默认会立即终止 upstream 连接,可加proxy_ignore_client_abort off(慎用,仅调试)
不复杂但容易忽略。











