aio threads 并非彻底剥离 I/O,而是让 worker 进程通过内核线程池异步执行 read() 并回调处理;必须满足内核≥5.1、XFS/ext4 文件系统、Nginx 启用 --with-file-aio、禁用 sendfile 且配合 directio 4m; 与显式 thread_pool 定义才能生效。

不能“彻底剥离”——aio threads 不是把 I/O 任务扔给别的进程,而是让当前 worker 进程在发起 read() 时不阻塞事件循环,靠内核线程池异步完成实际读盘,并通过回调通知 Nginx 继续处理。它仍是该 worker 的一部分,只是执行方式从同步等待变为非阻塞调度。
必须满足的硬性前提
配置 aio threads; 不等于生效,缺一不可:
- Linux 内核 ≥ 5.1(低版本仅支持
aio on,且依赖directio) - 文件系统为 XFS 或 ext4(btrfs、NTFS-3G 等不保证稳定)
- Nginx 编译启用
--with-file-aio(主流发行版包通常已开启) - 静态文件未被
mmap或sendfile直接绕过(aio对sendfile无效,只对read()路径起作用)
关键配置组合
单独写 aio threads; 没用,必须配合以下三项协同触发:
-
强制走 aio 路径:加
directio 4m;(例如 4MB 以上文件启用直接 I/O,绕过 page cache,逼出 aio) -
禁用冲突机制:确保
sendfile off;(二者互斥,sendfile优先级更高) -
减少重复开销:配
open_file_cache max=1000 inactive=30s;,避免反复open()带来的 inode 查找压力
线程池需显式定义与绑定
必须在 main 块中定义线程池,并在 location 中明确绑定:
- 定义池:
thread_pool disk_io threads=32 max_queue=4096;(建议线程数 = CPU 核心数 × 2~4) - 启用路径:
location /static { aio threads=disk_io; directio 4m; sendfile off; } - 注意:
aio threads=xxx中的xxx必须与thread_pool名称一致,否则静默失效
验证是否真正解耦
不看吞吐数字,盯住两个硬指标:
- Worker 线程在
top中 S 态(不可中断睡眠)占比持续 < 5% - I/O 线程池任务队列平均等待时间 < 10ms(可通过
/proc/.../status或自定义监控采集) -
iostat -x查aqu-sz,若持续高于线程数,说明底层磁盘已成瓶颈,需扩容池或换 NVMe

















