必须同时启用sendfile on、tcp_nopush on和tcp_nodelay off,且避开gzip、代理、内容改写及非本地文件等失效条件,才能真正触发内核零拷贝;仅配sendfile on无效。

要让 Nginx 真正用上 sendfile 零拷贝加速静态文件传输,不能只写 sendfile on; —— 必须三要素齐备、退化条件全避开,内核才能走直通路径:磁盘页缓存 → 网卡,不进用户态、不拷贝、不切换上下文。
必须同时启用的三个指令
这三项缺一不可,且需在同一作用域(推荐放在 http 块或具体 location 中):
- sendfile on;:开启零拷贝能力,是整条路径的启动开关
- tcp_nopush on;:配合 sendfile,让内核攒满 TCP 包再发,减少小包数量,提升吞吐
-
tcp_nodelay off;:关闭 Nagle 算法;设为
on会强制立即发包,直接废掉tcp_nopush的攒包效果
确保文件满足零拷贝前提
即使配置全对,只要文件不“够格”,Nginx 就会自动回退到低效的 read()+write() 模式:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 文件必须是本地真实磁盘文件(ext4/xfs 推荐),不能是 NFS、CIFS、FUSE 或容器卷挂载点
- 不能启用
gzip、gunzip、gzip_static(压缩必须在用户态做,会绕过零拷贝)——若需压缩,改用预压缩的.gz文件 +gzip_static on;+gzip off; - 不能有内容改写行为:如
sub_filter、add_before_body、Lua 脚本修改响应体 - 不能走代理:禁用
proxy_pass、fastcgi_pass等,必须由root或alias直接提供文件 - 响应需带
Content-Length头(即不能是 chunked 编码)
按资源类型精准配置更稳妥
不建议在全局 http 块盲目开启,而是针对不同后缀做细粒度控制:
-
图片类:
location ~* \.(jpg|jpeg|png|webp|gif|avif|svg)$ { sendfile on; tcp_nopush on; tcp_nodelay off; gzip off; access_log off; } -
大文件类:
location ~ \.(mp4|zip|iso|tar\.gz|dmg)$ { sendfile on; tcp_nopush on; tcp_nodelay off; sendfile_max_chunk 512k; expires 7d; }(sendfile_max_chunk防止单次调用阻塞事件循环)
配套优化进一步释放性能
这些不改变零拷贝路径,但能减少干扰、提升稳定性:
-
open_file_cache max=10000 inactive=60s;:缓存文件句柄和元信息,降低重复
stat()和open()开销 - access_log off;:纯静态资源 location 中关闭日志,避免高并发下 I/O 成瓶颈
- expires 或 Cache-Control:配合浏览器缓存,从源头减少请求数量

















