7.4.2 sendfile与高效文件传输
sendfile与高效文件传输#
原理与收益#
sendfile 让内核直接在文件系统缓存与网卡缓冲区间传输数据,减少用户态参与、降低拷贝与上下文切换,适合静态文件的大吞吐分发。
预期收益
- CPU 占用下降
- 大文件下载吞吐提升
- 延迟降低(尤其高并发)
环境检查与启用步骤#
sendfile 为内核能力,不需额外安装,需确保内核与 Nginx 编译支持。
1) 检查 Nginx 编译参数
nginx -V 2>&1 | grep -o 'with-file-aio\|with-pcre\|with-http_gzip_static_module'
2) 检查系统内核版本
uname -r
3) 配置并验证
文件路径:/etc/nginx/nginx.conf
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server {
listen 80;
server_name static.example.com;
location /static/ {
root /data/www;
# 大文件禁用压缩,避免 sendfile 被绕过
gzip off;
}
}
}
4) 语法检查与重载
nginx -t
systemctl reload nginx
预期效果
- 静态文件响应速度提升
- nginx -t 返回 ok,访问 /static/large.iso 能稳定下载
关键参数与命令解释#
sendfile on;:开启零拷贝传输tcp_nopush on;:合并包头,减少小包tcp_nodelay on;:小响应低延迟keepalive_timeout 65;:控制长连接空闲时间
示例:对小文件与大文件差异化优化#
http {
sendfile on;
# 小文件优先低延迟
location ~* \.(css|js|png|jpg)$ {
root /data/www;
tcp_nodelay on;
tcp_nopush off;
expires 7d;
}
# 大文件优先吞吐
location /download/ {
root /data/www;
tcp_nodelay off;
tcp_nopush on;
sendfile on;
}
}
性能验证与监控#
1) 观察系统调用
sudo strace -p $(pidof nginx | awk '{print $1}') -e trace=sendfile -tt
预期:出现 sendfile(...) = N 表示启用生效
2) 对比响应耗时
curl -o /dev/null -s -w 'time_total=%{time_total}\n' http://static.example.com/download/big.iso
3) 监控磁盘与网络吞吐
iostat -xm 1 3
sar -n DEV 1 3
常见问题排查#
-
下载文件损坏/大小不一致
处理:临时关闭 sendfile 验证
nginx sendfile off;
原因:旧内核或第三方模块兼容问题 -
小文件响应变慢
处理:对小文件关闭tcp_nopush或sendfile
nginx location ~* \.(css|js)$ { sendfile off; tcp_nopush off; } -
反向代理无提升
原因:sendfile 仅对静态文件直读有效
处理:确认root直读,或改用proxy_cache缓存
练习#
1) 在测试环境对同一大文件开启/关闭 sendfile,对比 curl 下载时间。
2) 使用 strace 观察 sendfile 系统调用是否出现。
3) 设计一个包含小文件与大文件的虚拟主机,分别设置不同的 tcp_nopush/tcp_nodelay 组合,记录效果。