sendfile 是 Nginx 静态文件服务性能关键开关,需满足内核零拷贝条件并协同 tcp_nopush、禁用 gzip 等限制才生效;错误配置如 proxy_pass 中启用或与 gzip 共存将使其失效。

sendfile 是 Nginx 静态文件服务性能的关键开关,不是“开了就快”,而是有明确生效条件和协作要求。它本质是启用内核级零拷贝传输,绕过用户空间,大幅降低 CPU 和内存开销——但只在合适场景下才真正起效。
基本语法与作用范围
指令格式很简单:
-
sendfile on;或sendfile off; - 可出现在
http、server、location块中,遵循配置继承规则(子块未定义时沿用父块) - 默认值为
off,生产环境建议显式设为on
必须配合的协同配置
单独开启 sendfile on 不等于零拷贝就跑起来了。以下两个指令是它的“黄金搭档”:
-
tcp_nopush on;:仅在sendfile启用时有效,它让 Nginx 等待 TCP 缓冲区填满或连接关闭时再发包,避免大量小包,提升吞吐 -
tcp_nodelay off;(默认即 off):不建议改为on,否则会破坏tcp_nopush的优化效果
常见错误:只开 sendfile 却没配 tcp_nopush,导致零拷贝虽启用,但网络层仍低效。
实际生效的隐藏条件
即使语法正确、协同配置齐全,Nginx 仍可能自动退回到传统 read/write 路径。关键限制包括:
- 响应体不能被修改:禁用
gzip、sub_filter、ssi、chunked transfer encoding等需用户态处理的功能 - 文件必须是普通磁盘文件:不支持管道、套接字、/proc 或加密文件系统挂载点等特殊路径
- SSL/TLS 场景下完全失效:OpenSSL 必须在用户空间完成加解密,数据无法直通内核
- 文件大小不宜过小:极小文件(如 <1KB)走零拷贝收益微弱,Nginx 可能内部优化跳过
新手最常踩的三个配置陷阱
这些错误不会导致 Nginx 启动失败,但会让 sendfile 形同虚设:
- 在启用了 gzip 的 location 下盲目开 sendfile:压缩必须在用户空间完成,两者互斥。应按需分离——静态资源走纯 sendfile,动态内容走 gzip
- 把 sendfile 放在 proxy_pass 的 location 里:反向代理响应由后端生成,Nginx 只是转发,不涉及本地文件读取,sendfile 完全不参与
-
忽略系统级限制:若内核版本低于 2.4,或文件系统不支持页缓存(如某些 FUSE 实现),零拷贝无法启用。可通过
strace -e trace=sendfile nginx-worker-pid观察是否真调用 sendfile() 系统调用


















