必须配置 sendfile_max_chunk 是为防止大文件传输卡死 worker 进程、避免阻塞其他请求,保障服务稳定性;默认 sendfile on 会一次性交整个文件给内核,导致进程独占、缓冲区满、重传超时及 502/504 频发。

直接在业务路径中启用 sendfile_max_chunk,不是为了“提升速度”,而是防止大文件传输卡死 worker 进程、避免阻塞其他请求——关键在稳定性,而非单纯性能。
为什么必须配 sendfile_max_chunk?
默认开启 sendfile on 后,Nginx 会尝试把整个文件一次性交给内核发送。若遇到几百 MB 的视频或安装包,单次系统调用可能耗时长、占用大量内存,导致:
- worker 进程被长时间独占,无法响应新连接
- 内核 socket 缓冲区填满,触发重传或超时
- 在高并发下出现连接堆积、502/504 频发
只对 /download/ 路径生效的配置写法
不要全局设置,精准作用于实际承载大文件的 location:
location ^~ /download/ {
alias /var/www/static/files/;
sendfile on;
sendfile_max_chunk 256k;
tcp_nopush on;
# 关闭 gzip(二者冲突)
gzip off;
# 可选:限制单个连接最大带宽,防突发打满
limit_rate 2m;
}说明:
-
^~前缀确保该规则优先于正则匹配,避免被覆盖 -
sendfile_max_chunk 256k表示每次最多交 256KB 给内核,分批传输,释放 worker -
tcp_nopush on必须配合sendfile,让每个 TCP 包尽可能装满,减少小包数量 -
gzip off是硬性要求,否则sendfile自动失效(压缩需用户态处理)
搭配 directio + aio 应对超大文件(如 >1GB)
当文件普遍超过 1GB,且服务器使用 XFS 文件系统时,可进一步启用 Direct I/O 避免 page cache 污染:
location ^~ /media/archive/ {
alias /storage/archive/;
sendfile on;
directio 4m;
aio on;
output_buffers 1 256k;
# 不再依赖内核缓存,适合冷数据高频读
open_file_cache off;
}注意点:
-
directio 4m表示 ≥4MB 的读取走 O_DIRECT,绕过内核 page cache -
aio on启用异步 I/O,避免 directio 阻塞 worker(Linux 2.6.22+ 支持) - 此时
sendfile和directio并存是合法的:小块走 sendfile,大块走 directio + aio
验证是否生效
不靠猜,用命令确认:
- 检查配置语法:
nginx -t - 查看运行中 worker 是否启用零拷贝:
strace -p $(cat /var/run/nginx.pid) -e trace=sendfile,应看到频繁调用 - 压测时观察
nginx -s status或ss -i中 retransmit、rto 等指标是否明显下降


















