sendfile_max_chunk的核心作用是防止单个大文件下载卡死worker进程、避免阻塞其他请求,解决稳定性问题而非提速;它通过限制每次sendfile调用的数据上限(如256k),使worker能及时返回事件循环,保持调度活性,同时需配合gzip off、tcp_nopush及精准location配置才生效。

sendfile_max_chunk 的核心作用不是提速,而是防止单个大文件下载卡死 worker 进程,避免阻塞其他请求——它解决的是稳定性问题,不是带宽或吞吐瓶颈。
为什么大文件会“卡死” worker?
默认 sendfile on 时,Nginx 会尝试把整个文件一次性交给内核 sendfile(2) 系统调用。遇到几百 MB 甚至 GB 级的视频、安装包时:
- 单次系统调用可能耗时数百毫秒甚至更久,期间该 worker 完全无法处理新连接或其它请求
- 内核 socket 发送缓冲区容易被填满,触发 TCP 重传或超时
- 高并发下多个大文件请求堆积,引发连接等待、502/504 频发
sendfile_max_chunk 怎么起作用?
它不是让内核分片,而是让 Nginx 主动控制每次调用 sendfile 的数据上限。设为 256k,意味着:
- Nginx 每次只交最多 256KB 给内核,发送完立刻返回事件循环
- worker 得以及时响应其他请求,保持调度活性
- 实际传输仍是零拷贝(DMA 直通),不损失 sendfile 的效率优势
怎么配才真正生效?
必须配合关键配套指令,否则可能无效或降级:
-
只在真实承载大文件的 location 中启用,例如
location ^~ /download/,避免影响小文件路径 - 必须关闭 gzip:gzip 是用户态压缩,与 sendfile 的内核零拷贝冲突,开启即自动禁用 sendfile
- 建议开启 tcp_nopush:配合 sendfile 把数据攒够 TCP MSS 再发,减少小包数量
- 超大文件(>1GB)建议叠加 aio + directio:避免同步磁盘读阻塞,真正卸载 IO 压力
常见误区提醒
这个参数常被误解:
- 它不能替代限速(limit_rate),也不影响最终下载速度,只管调度公平性
- 不是全局 http 块配置项,也不能写在 server 块里生效——必须落在具体 location
- 值不是越大越好:256k~512k 是较稳妥区间;设太大仍可能卡住,太小则增加系统调用开销
- 它不解决磁盘 I/O 瓶颈本身,只是缓解因 I/O 阻塞导致的 worker 不可用










