nginx的non-blocking i/o不提升单个大文件下载速度,但支撑高并发与稳态传输;关键优化包括关闭proxy_buffering实现流式透传、启用sendfile零拷贝、延长超时、按需配置directio及系统级调优。

Nginx 的 Non-blocking I/O 本身不提速单个大文件的下载速度,但它是支撑高并发、稳态传输、低资源开销的底层基础。优化大文件下载性能,关键在于让 Non-blocking 机制真正“发挥出来”——避免缓冲堆积、规避内核瓶颈、减少拷贝路径,并匹配真实链路限制。
合理关闭或精细控制 proxy_buffering
大文件传输时,开启 proxy_buffering on 会让 Nginx 缓存整个后端响应体,极易引发内存暴涨甚至 OOM。尤其当多个用户同时下载 GB 级文件,缓冲区未及时释放会迅速吃光 worker 内存。
- 对流式下载(如视频分片、ZIP 下载),直接设为:
proxy_buffering off;
- 若必须开启缓冲(例如需重写响应头),则严格限制大小:
proxy_buffer_size 128k; proxy_buffers 8 1m; proxy_busy_buffers_size 2m;
启用 sendfile + tcp_nopush,走零拷贝路径
静态文件直传场景下,sendfile on 可让内核在磁盘和 socket 之间直接搬运数据,完全绕过用户态内存拷贝,显著降低 CPU 和内存压力。
- 必须配合:
sendfile on; tcp_nopush on; # 合并 TCP 包,减少小包发送 tcp_nodelay off; # 避免 Nagle 算法干扰大块传输
- 注意:若启用了
directio(见下文),sendfile必须关掉,二者互斥。
为大文件请求单独配置超时与连接行为
Non-blocking 依赖事件驱动,但默认超时值(60s)对大文件极不友好,慢速网络或长尾传输极易触发 504。
- 在对应 location 中延长关键超时:
proxy_read_timeout 3600; # 后端读取响应的时间(如 PHP 打包 ZIP) proxy_send_timeout 3600; # 向客户端发送响应的时间 client_header_timeout 60; client_body_timeout 3600; # 上传大文件时也要调高 keepalive_timeout 600; # 长连接保持,减少重复建连开销
按需启用 directio,避开 page cache 干扰(仅限特定场景)
当文件远大于可用内存(如单个 20GB 镜像)、且后端是 NVMe/裸设备、监控显示 pgpgin/pgpgout 持续抖动时,可考虑 directio:
- 配置示例:
location /download/ { alias /data/mirror/; directio 4m; # ≥4MB 文件才启用 directio_alignment 512; # 对齐存储扇区 output_buffers 1 128k; # 减少用户态缓冲次数 sendfile off; # directio 与 sendfile 不共存 } - 验证是否生效:用
strace -e trace=io_submit,pread64 -p $(pidof nginx)观察是否调用io_submit。
补充:系统级协同调优不能少
Non-blocking 效果再好,也受限于底层:
- 调大内核 socket 缓冲区:
net.core.rmem_max = 16777216 net.core.wmem_max = 16777216
- 确保
ulimit -n足够(建议 ≥65535),避免连接数受限; - 使用
worker_processes auto;和worker_connections 10240;充分利用多核与连接池。
不复杂但容易忽略。











