必须同时启用sendfile on、tcp_nopush on和tcp_nodelay off,且避开gzip、代理、无Content-Length等退化条件,才能真正触发内核零拷贝;仅对真实本地静态文件生效,单独配置任一指令均无效。

要让 Nginx 在高并发下真正靠 sendfile 高效分发静态资源,不能只写一行 sendfile on;。它必须成套启用、精准作用、避开退化路径,否则会悄无声息回退到低效的 read/write 模式。
必须同时开启的三个核心指令
缺一不可,且需在生效的 location 或 http 块中统一配置:
- sendfile on;:激活内核零拷贝能力,让数据从磁盘 fd 直送 socket fd
- tcp_nopush on;:依赖 sendfile 路径,将响应头与文件数据合并进同一 TCP 报文段,减少小包
- tcp_nodelay off;:关闭 Nagle 算法;设为 on 会强制立即发包,直接抵消 tcp_nopush 效果
只对真实本地文件生效,这些情况会自动退化
即使配置全对,只要出现以下任一情形,Nginx 就会放弃 sendfile,改用用户态搬运:
- 启用了
gzip on、gunzip on或gzip_static on(但 .gz 文件缺失时 fallback) - 使用了
proxy_pass、fastcgi_pass、sub_filter、add_before_body等内容改写或代理指令 - 文件位于 NFSv3、FUSE、Docker 默认存储驱动挂载点等不支持 sendfile() 系统调用的文件系统
- 响应缺少
Content-Length(如动态生成或对象存储直传未返回明确长度)
按资源类型做细粒度 location 配置
避免全局一刀切,推荐针对后缀精准启用:
-
图片类:
location ~* \.(jpg|jpeg|png|webp|gif|avif|svg)$ { root /var/www; sendfile on; tcp_nopush on; tcp_nodelay off; gzip off; expires 1h; } -
大文件类:
location ~ \.(mp4|zip|iso|tar\.gz|dmg)$ { sendfile on; tcp_nopush on; tcp_nodelay off; sendfile_max_chunk 512k; expires 7d; }
sendfile_max_chunk 512k 可防止单次传输阻塞事件循环,兼顾高清图与短视频首段加载。
辅助优化项,进一步释放性能
这些不改变零拷贝路径,但能显著降低干扰:
-
access_log off;:静态 location 中关闭日志,避免高并发 I/O 成瓶颈 -
open_file_cache max=10000 inactive=60s;:放在 http 块中,缓存句柄与元信息,减少重复 open/stat - 确保
root指向真实本地目录(如 ext4/xfs),且 Nginx worker 进程有读权限


















