开启 sendfile 可将静态文件传输从四次拷贝降为两次,仅需2次数据拷贝和2次上下文切换,显著降低CPU sys占用与延迟;禁用后回退至read/write模式,导致CPU搬运开销激增,高并发下QPS下降20%–40%。
开启 sendfile 能显著降低静态文件传输的 CPU 开销和延迟,禁用后则回归传统 read/write 模式,带来额外拷贝与上下文切换——性能差异在高并发下载或大量小资源请求场景下尤为明显。
启用 sendfile 后,Nginx 利用内核原生 sendfile() 系统调用,实现磁盘到网卡的内核直传:
整个过程仅需 2 次数据拷贝、2 次上下文切换。而禁用时,必须走用户态路径:
CPU 时间大量消耗在搬运上,尤其在 100+ 并发静态请求时,sys(系统态)CPU 使用率可升高 3–5 倍,QPS 下降 20%–40%。
真实评估需避开缓存干扰,并关注稳定性与系统负载:
echo 3 > /proc/sys/vm/drop_caches,避免 page cache 掩盖差异curl -s -w "%{speed_download}n" -o /dev/null http://x/file.zip,统计下载速率标准差;开启 sendfile 后标准差通常降低 30% 以上pidstat -d 1 观察 worker 进程的 %iowait 和 kB_rd/s,sendfile 开启后 iowait 明显下降,说明 I/O 更高效ab -n 200 -c 50 http://x/file.css 对比 QPS 与平均响应时间;禁用时响应时间抖动更大,长尾更明显配置了 sendfile on 不代表一定走零拷贝路径,必须验证实际行为:
strace -p $(pgrep nginx | head -1) -e trace=sendfile64,read,write 2>&1 | grep sendfile64,持续看到 sendfile64 调用才确认启用gzip on、Range 请求或 etag 指令,Nginx 会自动回退到 read/write,此时 strace 将显示 read 和 write
/proc/<pid>/fd/ 查看 socket fd 与文件 fd 是否被同一 sendfile64 调用串联,是零拷贝的关键证据不是所有情况都适合开启,以下情形建议关闭或无法启用:
gzip on:运行时压缩必须进用户态,强制禁用 sendfilesendfile() 系统调用,Nginx 自动 fallbackdirectio 优化大文件下载:二者冲突,必须 sendfile off
禁用后虽损失零拷贝优势,但换来内容可干预能力——比如动态加水印、按需转码或插入响应头。