sendfile_max_chunk的核心作用是为大文件传输设置分段上限,避免worker进程被长时间占用,从而保障服务响应稳定性;它不提升速度,仅通过主动让出CPU维持整体调度平衡。

sendfile_max_chunk 的核心作用,是给大文件传输“加呼吸点”,避免一个几百 MB 甚至几 GB 的下载请求把整个 worker 进程卡死,导致其他小请求排队、超时、返回 502/504。
它不提速,也不减少总下载时间,而是让 Nginx 在传输大文件时主动分段、让出 CPU,从而维持服务整体的响应稳定性。
只在真正需要的地方启用
不是所有静态资源都要配。重点锁定实际承载大文件的路径,比如 /download/、/video/、/dist/ 等:
location ^~ /download/ {
alias /data/files/;
sendfile on;
sendfile_max_chunk 1m;
tcp_nopush on;
gzip off;
limit_rate 3m;
}-
^~前缀确保优先匹配,防止被正则 location 覆盖 -
sendfile on必须显式开启,否则sendfile_max_chunk完全无效 -
gzip off是硬性要求:压缩必须在用户态做,和零拷贝(sendfile)互斥 -
tcp_nopush on配合 sendfile,让每个 TCP 包尽量装满,减少网络小包
合理设置 chunk 大小
数值不是越大越好,也不是越小越稳,关键看你的业务特征:
- 512k(524288):适合 API + 小资源混合场景,对延迟敏感,worker 让出更频繁
- 1m(1048576):通用推荐值,吞吐与调度平衡,多数 CDN 和下载站采用
- 2m(2097152):带宽充足、连接数不高、文件普遍 >500MB,比如内部镜像源
不建议:
- 低于 64k:系统调用太频繁,效率反降
- 高于 4m:一次搬运仍可能持续几十毫秒,失去“释放 worker”的意义
必须配合的关键配置
单设 sendfile_max_chunk 效果有限,以下三项需同步检查:
-
sendfile on;—— 基础前提,缺一不可 -
tcp_nopush off;?错!实际应为tcp_nopush on;(多数资料已修正):它和sendfile协同,攒够数据再发,提升网络效率;但注意它不与sendfile_max_chunk冲突,反而是增强分块后的传输质量 -
aio threads;+directio 4m;(可选但强烈推荐):针对 >1GB 文件或机械盘,绕过 page cache,用线程池异步读盘,彻底卸载 I/O 压力
示例增强配置:
location ^~ /mirror/ {
alias /mnt/storage/mirror/;
sendfile on;
sendfile_max_chunk 2m;
tcp_nopush on;
gzip off;
aio threads;
directio 4m;
}验证是否生效
改完别急着上线,用这几招确认真实起效:
- 用
strace -p $(pgrep nginx) -e trace=sendfile64观察count=参数,应稳定在你设的值附近(如count=1048576) - 压测时监控
nginx_stub_status:大文件下载中,Writing数应平稳,不持续飙升 - 对比配置前后,相同并发下小请求的 P95 延迟——若大文件下载时小请求延迟波动明显收窄,说明 worker 调度已改善
不复杂但容易忽略。

















