sendfile 指令在 Nginx 中控制内核态零拷贝传输,支持 http/server/location 作用域,不支持 if 或嵌套 location;继承方式为向下覆盖式,且开启时会静默禁用 gzip 等依赖用户态缓冲的模块。

sendfile 指令在 Nginx 中控制是否启用内核态零拷贝传输文件,它支持在 http、server 和 location 三个作用域中配置,但**不支持在 if 块或嵌套 location 中使用**。它的继承行为是“向下覆盖式”,即子块未显式声明时,继承父块的值;一旦子块设置了该指令,就完全覆盖父块设置,且不会叠加或合并。
http 块中配置:全局默认值
在 http 块中设置 sendfile on; 或 sendfile off;,会作为所有 server 和 location 的默认值。适合统一开启/关闭零拷贝(例如静态资源服务器普遍开启,而调试环境或某些代理场景需关闭)。
- 若只在
http块写sendfile on;,所有 server 和 location 默认生效 - 若
http块未配置,Nginx 默认值为off(注意:不同版本可能有差异,1.10+ 默认为off,但建议显式声明)
server 块中配置:按虚拟主机差异化控制
在 server 块中设置,可覆盖 http 块的值,适用于同一 Nginx 实例下多个站点策略不同的情形。例如主站静态资源多,开启 sendfile;管理后台涉及动态响应或调试,关闭它便于抓包或兼容某些旧客户端。
- server 级配置对本虚拟主机下所有 location 生效,除非被 location 显式覆盖
- 不能仅靠 server 块“部分启用”——比如想让 /static 开启、/api 关闭,必须进 location 细粒度控制
location 块中配置:最细粒度的开关控制
在 location 块中设置,可精确控制某类路径的行为。典型用法是:对静态文件目录(如 location ~* \.(jpg|css|js)$)强制开启 sendfile on;,而对需要 body filter 或流式处理的接口(如 location /download)设为 off。
- location 中的
sendfile会完全覆盖 server 和 http 的设置 - 注意:当
sendfile on;时,proxy_buffering、gzip、sub_filter等依赖用户态缓冲的模块将自动失效(Nginx 会静默禁用),这是常见排查盲点 - 若 location 内同时用了
sendfile on和gzip on,gzip 不会生效,且日志中无报错,需通过响应头或 tcpdump 验证
实际排查建议
遇到 sendfile 行为异常(如预期加速但没生效、或 gzip 突然失效),按以下顺序检查:
- 用
nginx -T | grep -A2 -B2 sendfile查看完整生效配置,确认最终落在哪个块 - 检查当前请求匹配的 location 是否隐式继承了上级配置,还是被其他 location 块覆盖(注意正则 location 优先级)
- 确认是否与
tcp_nopush、tcp_nodelay、gzip、limit_rate等指令冲突(sendfile on 时,limit_rate 仍有效,但作用机制变为 socket level 限速) - 在调试时,可在 location 中临时加
add_header X-Sendfile $sent_http_x_sendfile;(配合自定义变量)辅助判断,但更推荐用curl -I观察 Content-Length 和 Transfer-Encoding,或用strace -e trace=sendfile64直接验证系统调用


















