output_buffers 仅在同时满足“本地静态文件、sendfile off、aio on + directio、含 Content-Length 的非分块响应”四条件时生效,需与 aio/directio 协同配置;设为 1 个 128KB 缓冲区可平衡系统调用频次与内存占用,盲目增大 number 或 size 反致同步回退或 OOM。

配置 output_buffers 来调优大文件下发,并**不是简单地“调大就变快”**。它只在特定异步缓冲路径下起作用,且必须和 aio + directio 配合使用——此时 Nginx 放弃内核零拷贝(sendfile off),改用用户态异步读 + 分段内存缓冲写入 socket 的模式。
明确生效前提:必须同时满足这4个条件
只有全部满足,output_buffers 才真正参与数据流:
- 请求的是本地静态文件(
alias或root指向磁盘路径,非 proxy_pass) -
sendfile off(禁用零拷贝,强制 Nginx 自己读文件) - 启用了
aio on和匹配的directio(如directio 4m) - 响应含
Content-Length、无Transfer-Encoding: chunked(即非范围请求 206)
与 aio/directio 协同配置的关键写法
典型适用于视频、ISO、大安装包等场景。示例配置:
location /downloads/ {
alias /data/files/;
aio on;
directio 4m; # ≥4MB 文件走 O_DIRECT + AIO
output_buffers 1 128k; # 每次提交最多用 1 个 128KB 缓冲区
sendfile off; # 必须关闭,否则 aio 和 directio 不生效
tcp_nopush off; # 避免 Nagle 算法延迟小包发送
}说明:
-
output_buffers 1 128k表示:每次异步 I/O 完成后,Nginx 最多用 1 个 128KB 缓冲区暂存数据,再批量写入 socket - 设为
1个缓冲区,是为了避免与directio对齐冲突;多个缓冲区可能造成非对齐写,触发同步回退 -
128k是平衡点:比默认32k减少系统调用频次,又不显著增加单次内存占用
为什么不能随便加大 number 或 size?
在 aio + directio 场景下,盲目调高反而破坏效率:
-
number > 1(如4 128k)会导致 Nginx 尝试并行分配多个缓冲区,但directio要求严格块对齐,多缓冲易引发 fallback 到同步读 -
size > 256k(如1m)会增大单次内存申请压力,尤其在高并发下载时,worker 进程 RSS 快速攀升,可能触发 OOM - 真正影响吞吐的瓶颈常在磁盘 I/O 延迟、TCP 接收窗口、客户端带宽,而非该缓冲区大小
验证是否按预期工作
仅靠配置不等于生效,需实测确认:
- 开启 debug 日志:
error_log /var/log/nginx/error.log debug;,然后搜索output buffer或aio read关键字 - 用
strace -p $(pgrep nginx) -e trace=read,write,io_submit观察是否出现io_submit系统调用 - 对比启用前后,相同文件在慢网环境(如 tc netem 加 100ms 延迟)下的平均下载速率和连接抖动


















