output_buffers仅在Nginx用户态读静态文件、sendfile off、含Content-Length、未启用aio/directio时生效;推荐设为2 128k或4 64k,避免number过大引发OOM,优先使用sendfile on更高效。
output_buffers 不是单纯“调大数量就能优化读写性能”的通用缓冲开关。它只在非常特定的路径下起作用:Nginx 自己读磁盘文件 → 写入 socket(即绕过内核零拷贝),且响应必须是完整、已知长度、非分块的静态文件下发。
要让它真正参与磁盘到网络的数据流转,必须同时满足四个硬性条件:
root 或 alias 指向磁盘路径,不是 proxy_pass)sendfile off;(禁用零拷贝,强制 Nginx 用户态读取)Content-Length 且不含 Transfer-Encoding: chunked
aio 和 directio(二者会跳过 output_buffers,走异步 I/O + 自定义缓冲路径)只有全部满足,output_buffers 才控制 Nginx 从磁盘读完一段后、往 socket 写之前所用的内存缓冲区。
output_buffers number size 中的 number 表示最多可同时分配的缓冲区个数,不是“预分配”或“常驻”。它影响的是:
size 时,Nginx 是否需要多次 read() + write() 循环number 过大会导致 worker 进程内存占用陡增,尤其并发连接多时易 OOM推荐组合(针对百 MB 级静态文件,如 .zip、.mp4):
output_buffers 2 128k;write() 系统调用频次,又不显著拉高单连接内存开销 output_buffers 4 64k;output_buffers 8 1m;aio on; directio 4m; → output_buffers 被完全绕过,此时应调 output_buffers 1 128k(仅在 aio+directio 模式下有意义,且必须设为 1 个缓冲区以对齐 DMA 传输)sendfile on; → Nginx 直接交由内核 sendfile() 完成,output_buffers 不参与任何环节206 Partial Content 或 chunked → output_buffers 不激活,改走流式发送路径write()
别只看配置写了没,用真实行为确认:
strace -p $(pgrep nginx) -e trace=write,sendfilewrite() 调用、几乎无 sendfile(),说明走的是 output_buffers 路径 ps aux | grep nginx 对比开启/关闭 sendfile 后的内存变化 error_log ... debug;,搜索日志中是否有 output buffer 相关提示(需编译含 --with-debug)对绝大多数静态大文件分发,sendfile on; tcp_nopush on; 的组合比调优 output_buffers 更有效:
sendfile on:数据从 page cache 直达 socket,零用户态拷贝,CPU 和内存开销最低 tcp_nopush on:把响应头 + 响应体合并为一个 TCP 包发出,减少小包和 Nagle 延迟 output_buffers 完全不生效,也不需要调 —— 这才是 Nginx 处理静态文件的黄金路径只有当你明确不能用 sendfile(比如需要做 header 注入、加签、或文件权限校验必须走用户态读),才进入 output_buffers 调优范畴。
不复杂但容易忽略