必须关闭 proxy_request_buffering,否则 Nginx 会缓存整个请求体导致高延迟、内存暴涨、413 错误或超时;需同步配置 client_max_body_size、proxy_read_timeout、proxy_buffering 等参数,并确保后端支持流式读取。

关闭 proxy_request_buffering 并不能实现“零延迟转发”,但它能避免 Nginx 在收到完整请求体前就阻塞后端,从而让超大文件上传更早触达上游服务——这是流式上传的关键前提。
为什么 proxy_request_buffering off 是必要条件
Nginx 默认开启 proxy_request_buffering on,意味着它会把整个客户端请求(包括大文件)先缓存在内存或临时磁盘中,校验完所有头部、确认无误后再一次性转发给后端。这对小请求安全高效,但对 GB 级上传会造成明显延迟和内存/磁盘压力。
设为 off 后,Nginx 一旦解析完请求头,就立即建立与上游的连接,并将后续收到的请求体数据边收边转(类似管道),不等待上传完成。这显著降低首字节到达后端的时间(TTFB for upload)。
必须配套的 upstream 和 client 配置
仅关 buffering 不够,还需确保后端能真正接收流式数据,且客户端不会因超时中断:
-
延长超时时间:在 location 块中设置
proxy_read_timeout 3600、proxy_send_timeout 3600,防止 Nginx 在转发过程中主动断连 -
禁用缓冲代理体:添加
proxy_buffering off(影响响应,非必需但推荐)、proxy_request_buffering off(核心) -
适配后端协议:确保 upstream 服务支持 HTTP/1.1 分块传输(chunked encoding)或明确声明
Content-Length;若用 FastAPI/Flask,需启用流式 request body 解析 -
客户端注意:浏览器 FormData 上传天然支持分块;curl 可用
--data-binary @file.bin直接流式发送,无需额外编码
典型配置示例(Nginx + Python Flask 后端)
以下是最小可行配置片段:
location /upload {
proxy_pass https://backend;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
<pre class='brush:php;toolbar:false;'>proxy_request_buffering off;
proxy_buffering off;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
# 防止因大 body 被拒绝
client_max_body_size 0; # 0 表示无限制}
后端需按流读取,例如 Flask 中使用 request.stream.read(chunk_size) 而非 request.get_data()。
常见陷阱与验证方式
容易忽略的点往往导致“关了 buffering 却没效果”:
- SSL/TLS 层干扰:若 Nginx 前有 CDN 或 TLS 终结设备(如 ALB、Cloudflare),它们可能自带 buffering,需一并检查并关闭
-
HTTP/2 影响:Nginx 1.19.4+ 对 HTTP/2 请求默认忽略
proxy_request_buffering,若强制走 HTTP/2,该指令实际不生效;建议上传路径固定用 HTTP/1.1 -
验证是否生效:用
tcpdump或 Wireshark 抓包,观察客户端发包后几秒内,Nginx 是否已向 upstream 发出 SYN/first data;也可在后端加日志,打印request.environ.get('wsgi.input_terminated')是否为 True


















