sendfile_max_chunk 并非 Nginx 官方指令,在标准 Nginx(截至 1.25.x)中不存在,其出现多因误解、第三方模块或混淆内核行为;Nginx 不干预 sendfile(2) 单次搬运量,该值由内核根据 socket 缓冲区、页缓存对齐及 EOF 等决定。

sendfile_max_chunk 并非 Nginx 官方指令,它在标准 Nginx(截至 1.25.x)中并不存在。你实际看到的配置或文档中出现该指令,通常是误解、第三方模块引入,或混淆了内核行为与 Nginx 配置边界所致。
为什么不能靠 sendfile_max_chunk 控制传输块大小
Nginx 的 sendfile(2) 系统调用由内核完全管理,其单次搬运量取决于:
- socket 发送缓冲区大小(
net.core.wmem_default) - 文件剩余长度与页缓存对齐情况(如 4KB/64KB)
- 是否遇到 EOF、信号中断或缓冲区满
Nginx 本身不提供用户侧干预每次 sendfile 调用字节数的机制——这违背零拷贝“减少上下文切换”的设计初衷。所谓“设置 sendfile_max_chunk”在真实环境中不会生效,strace 观察到的 sendfile64 调用 count 参数也不会受其约束。
真正导致 Worker 被独占的原因
大文件下载卡住 worker,问题通常不在 sendfile 本身,而在于:
- 同步磁盘读取:当文件未命中 page cache,Nginx 需等待磁盘 IO 完成,进程阻塞
- 缺乏异步支持:仅开 sendfile on 不足以卸载读盘压力;需配合 aio + directio
- 无连接管控:单个超大下载长期占用连接,挤占事件循环资源
正确缓解 Worker 独占的实用配置
聚焦真实有效的组合策略:
-
启用异步读取:在 location 中添加
aio threads;和directio 4m;(适用于 ≥1GB 文件,XFS/ext4 支持),绕过 page cache,用线程池异步加载 -
限制单连接带宽:使用
limit_rate 2m;防止单请求吞尽网络与磁盘吞吐 -
精准启用 sendfile:只在静态资源路径(如
location ~ \.(mp4|zip|iso)$)中设sendfile on;,同时关闭 gzip、sub_filter 等禁用 sendfile 的功能 -
配合 tcp_nopush:设
tcp_nopush on;(仅在 sendfile 生效时起作用),提升 TCP 包利用率,减少小包干扰 -
优化系统级 IO 能力:调整
vm.swappiness、增大fs.file-max、启用io_uring(Linux 5.3+)等内核参数
如何验证优化是否到位
不要依赖不存在的指令,而是观察运行时行为:
- 用
strace -e trace=sendfile64 -p $(pgrep nginx)确认是否真在调用 sendfile - 压测时监控
nginx_stub_status中的 Writing 连接数:若大文件下载期间数值稳定、无持续堆积,说明 worker 未被锁死 - 用
iostat -x 1查看 await、%util 是否显著下降,确认磁盘压力减轻










