sendfile和output_buffers互斥:sendfile on时零拷贝生效,output_buffers被忽略;sendfile off且满足本地静态文件、无aio/directio、含content-length等条件时,output_buffers才生效,推荐设为2 128k。

sendfile 和 output_buffers 是 Nginx 中一对互斥而非协同的输出机制,调优的关键不在于“怎么配在一起”,而在于明确场景、选对路径、避免误配。
✅ sendfile on:零拷贝直传,高效默认路径
适用于静态文件(如图片、JS、CSS、视频片段)且无需修改响应体的场景。
此时:
- 数据从文件系统 page cache 直接送入 socket,内核完成,无用户态内存拷贝
-
output_buffers完全不生效,配置会被忽略 - 推荐搭配:
-
tcp_nopush on;—— 合并响应头与首个数据块,减少小包 -
tcp_nodelay off;(默认)—— Nagle 算法在此路径下有益,不干扰吞吐
-
⚠️ 注意:若启用了
aio on或directio,sendfile on会自动失效(Nginx 内部逻辑强制降级),需检查 error_log debug 日志确认是否真走 sendfile 路径。
✅ sendfile off:用户态分片读写,output_buffers 才入场
仅当必须由 Nginx 自己读文件(例如需加签、鉴权、动态重写 Content-Length、或绕过内核缓存)时启用。
此时生效前提必须全部满足:
- 请求的是本地静态文件(
root/alias,非proxy_pass) -
sendfile off; - 响应含
Content-Length,且不是206 Partial Content、不是chunked、不是 HTTP/2 流 -
未启用
aio+directio(否则走另一套异步缓冲逻辑,output_buffers仍不生效)
满足后,output_buffers number size 控制:
- 每次
read()后最多用number个缓冲区暂存数据 - 每个缓冲区最大
size,用于后续writev()批量发往 socket
推荐配置:
-
output_buffers 2 128k;—— 平衡小包数量与内存占用,比默认2 32k更适合大文件(如 >10MB) - 不建议
>4个或>256k单块:易引发 worker 内存波动,且无性能增益
❌ 常见误配组合(实际无效甚至有害)
-
sendfile on;+output_buffers 8 1m;→ 缓冲区配置被跳过,纯属浪费内存 -
sendfile off;+aio on; directio 4m;→ 进入 AIO 异步路径,output_buffers失效,应改用aio_write+output_buffers 1 128k(仅在特定 AIO 模式下有效) -
proxy_pass场景下配output_buffers→ Nginx 无该指令作用域,配置无效或报错 - 流式接口(SSE、日志 tail、导出流)中调大
output_buffers→ 完全不触发,卡顿根源在proxy_buffering on,应关它
? 如何验证是否走对路径?
开启 debug 日志:
error_log /var/log/nginx/debug.log debug;
搜索关键词:
-
sendfile: on或sendfile: off -
output buffer、writev、aio write -
http proxy(确认非代理路径)
再结合 strace -p $(pgrep nginx) -e trace=sendfile,read,writev 观察系统调用行为,可精准定位实际走哪条输出链路。











