sendfile_max_chunk 用于防止大文件传输长期独占 worker 进程,通过分块调用 sendfile 实现调度公平;需配合 sendfile on、tcp_nopush off、gzip off 等配置生效。

sendfile_max_chunk 的作用不是限制“网络带宽”,而是防止单个大文件传输长期独占 worker 进程,从而避免它无法响应其他请求——本质是调度公平性优化,不是网络层限速。
为什么大文件会“霸占”worker
默认开启 sendfile on 后,Nginx 会把整个文件一次性交给内核 sendfile() 系统调用。遇到几百 MB 或几 GB 的文件(如视频、镜像包),内核可能一次搬运上百 MB,导致:
- 该 worker 进程在本次连接上长时间不可调度,无法处理新连接、定时器或其他请求的读写事件
- socket 发送缓冲区持续打满,触发重传或超时,严重时引发 502/504
- Active connections 中 Writing 数持续高位,其他请求排队等待
sendfile_max_chunk 如何“松绑”worker
它强制 Nginx 将大文件分块推进:每次最多交指定字节数给内核,传输完立即让出 CPU,进入事件循环处理其他任务。相当于为长连接注入“呼吸点”。
- 值设为 512k(524288):适合高并发、小文件混合场景,响应更灵敏
- 值设为 1M(1048576):通用平衡值,多数下载站和 CDN 边缘节点采用
- 值不建议低于 64k(系统调用太频繁)或高于 4M(失去分片意义)
必须配合的关键配置
单独设 sendfile_max_chunk 无效,需同步调整:
- sendfile on:前提条件,否则指令不生效
- tcp_nopush off:避免其攒包行为抵消分块效果(注意:不是 on)
- gzip off:压缩必须在用户态做,与 sendfile 冲突,开启 gzip 会自动禁用 sendfile
- (可选)aio threads; directio 4m;:对 >1GB 文件进一步卸载磁盘读取压力,尤其在机械盘或 XFS 上
只对大文件路径精准启用
无需全局设置,推荐在实际承载大文件的 location 中启用:
location ^~ /download/ {alias /var/www/static/files/;
sendfile on;
sendfile_max_chunk 1m;
tcp_nopush off;
gzip off;
limit_rate 2m;
}
- ^~ 前缀确保规则优先级高于正则,防被覆盖
- limit_rate 是辅助手段,用于防单连接吃光带宽,和 sendfile_max_chunk 目标不同(后者管调度,前者管速率)

















