proxy_buffering 是 nginx 反向代理中控制响应缓存路径的关键开关,其行为取决于 proxy_buffers、proxy_max_temp_file_size 等参数协同:on 时按需分级缓冲(头→内存→磁盘),非全内存缓存;off 时纯流式转发。

proxy_buffering 是 Nginx 反向代理中控制响应是否缓存的关键开关,它直接决定数据走内存还是落磁盘。在高负载下,不当配置会引发 iowait 飙升、吞吐抖动甚至 502 错误——问题不在于“开或关”,而在于它如何与 proxy_buffers、proxy_max_temp_file_size 协同工作。
proxy_buffering on 的真实行为:不是全缓存,而是“按需分级”
开启时(默认值),Nginx 并非把整个响应体都塞进内存。它实际执行三段式处理:
- 先用 proxy_buffer_size(仅首块)暂存响应头,确保能解析状态码、Content-Length 等关键字段;
- 再用 proxy_buffers(多块缓冲区)接收响应体,边收边攒;
- 若响应体超出所有缓冲区总和,且 proxy_max_temp_file_size > 0,就写临时文件到磁盘;否则直接报错或中断连接。
也就是说,proxy_buffering on ≠ 全内存缓存,它只是打开了“缓冲路径”,后续是否落盘,由缓冲区容量和 proxy_max_temp_file_size 共同拍板。
为什么高并发下磁盘 IO 会突然暴增
典型诱因是大量中等大小响应(如 100–800MB 的报表、视频分片)反复触发“写临时文件 → 读临时文件 → 删除临时文件”循环:
- 默认 proxy_buffers 总大小仅 128KB(8×16k),远不够装下这类响应;
- proxy_max_temp_file_size 默认 1G,恰好让这些响应全部落入“写盘区间”;
- 每个请求都产生随机小 IO、inode 创建/删除、ext4 journal 刷盘,iowait 拉高,CPU 空转等待磁盘。
这不是磁盘性能差,而是 Nginx 主动选择了低效路径。
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
两种平衡策略:按场景选内存 or 流式
策略一:保留缓冲能力,彻底禁用磁盘写入
- 设 proxy_max_temp_file_size 0,强制跳过所有临时文件逻辑;
- 同步调大 proxy_buffers 16 256k(总 4MB),适配常见大响应;
- 设 proxy_busy_buffers_size 2m,保证转发接力不卡顿;
- 保持 proxy_buffering on,仍可加 Header、做重试、统一超时控制。
策略二:放弃缓冲,启用纯流式转发
- 设 proxy_buffering off,Nginx 边收边上发,内存占用最低;
- 此时 proxy_buffers、proxy_busy_buffers_size、proxy_max_temp_file_size 全部失效;
- 适合大文件下载、SSE、API 流式响应等无需修改响应头或重试的场景;
- 注意:上游若返回 Connection: close 或 Transfer-Encoding: chunked,可能绕过该设置,需实测确认。
必须避开的三个坑
即使参数调对,也常因细节翻车:
- location 块覆盖了全局 proxy_buffering,但忘了同步改 proxy_buffers——结果缓冲区太小,连接频繁 reset;
- access_log 未启用 buffer=64k flush=5s,日志刷盘本身就成了 IO 主力军;
- client_body_in_file_only on 或 fastcgi_buffering on,这些模块有自己的临时文件机制,和 proxy_* 参数无关,需单独排查。
用 iotop -o 查看具体 worker 进程的 IO,再用 lsof -p $PID 确认 fd 对应的是 proxy_temp 还是 access.log,才能准确定位源头。










