要真正提升静态文件传输效率,必须同时启用sendfile on、tcp_nopush on和tcp_nodelay off,三者缺一不可且须同处location块中;仅对大静态资源(如.mp4、.zip)有效,小文件、动态响应或HTTPS等场景无效甚至有害。

要真正提升静态文件传输效率,sendfile 和 tcp_nopush 必须成对启用、位置一致、避开干扰项——单独开任何一个都几乎没效果。
必须同时配置的三个基础指令
这三项缺一不可,且需写在同一 location 块中(不能只靠 http 或 server 块继承):
- sendfile on;:激活内核零拷贝路径,让数据从磁盘页缓存直接送入 socket 缓冲区
- tcp_nopush on;:依赖 sendfile 生效,把响应头和文件开头数据合并进同一个 TCP 报文段,减少小包数量
- tcp_nodelay off;:显式关闭 Nagle 算法,避免它强制立即发包,破坏 tcp_nopush 的攒包逻辑
只在适合的场景启用,不全局硬套
这些优化对小文件、动态响应、HTTPS 流量或代理转发基本无效,甚至可能增加首字节延迟。推荐按文件类型精准启用:
- 视频、安装包、镜像等大静态资源(如 .mp4、.zip、.iso、.dmg):强烈建议启用
- 图片、CSS、JS 等中小资源:可启用,但收益有限;若已用 gzip_static,需确保 gzip off
- 动态接口、proxy_pass 后端、含 sub_filter / add_header 的 location:自动退化,无需配置
示例配置:
location ~ \.(mp4|zip|iso|tar\.gz)$ {root /data/assets;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
gzip off;
access_log off;
}
避开常见退化条件
即使配置全对,以下情况也会让 Nginx 自动回退到传统 read/write 模式,彻底绕过 sendfile:
- 启用了 gzip on(压缩会改写响应体,破坏零拷贝)
- 使用了 proxy_pass、fastcgi_pass 等反向代理指令
- 配置了 sub_filter、add_header(尤其 header 超大时)
- 服务的不是本地磁盘文件(如 NFS、CephFS 等不支持 sendfile 的文件系统)
- 文件被 open_file_cache invalid 重载,或权限/路径异常导致 fallback
配合其他关键调优项
单靠 sendfile + tcp_nopush 效果有限,还需组合发力:
- sendfile_max_chunk 512k;:限制单次 sendfile 传输上限,防止单个大文件阻塞 worker 进程
- open_file_cache max=10000 inactive=30s;:缓存文件句柄与元信息,减少 stat/open 系统调用
- expires 或 Cache-Control:减轻重复请求压力,间接提升吞吐稳定性
- limit_rate(可选):对下载类 location 限速,防止单连接打满带宽影响其他请求



















