不能在 events 块中配置 aio 实现真正的异步磁盘 IO,因为 aio 指令作用域仅限于 http、server 或 location 块,且必须配合 directio、关闭 sendfile、满足内核与文件系统条件才能生效。

不能在 events 块中配置 aio 实现真正的异步磁盘 IO。
aio 是 Nginx 中用于启用内核级异步文件读取的指令,但它完全不隶属于 events 块。把 aio on; 或 worker_aio_requests 放进 events { ... } 里会导致 Nginx 启动失败,报错类似:
nginx: [emerg] "aio" directive is not allowed here
这是因为 aio 的作用域仅限于 http、server 或 location 块,且必须配合其他条件才能生效。
真正起效的 aio 配置要点
-
只对大文件顺序读有效:典型场景是视频分片(
.mp4/.ts)、镜像下载(.iso)等静态资源服务。 -
必须开启
directio:例如directio 4m;表示 ≥4MB 的文件才走 direct I/O + aio 路径;小文件仍走 page cache + 同步 read。 -
依赖内核与文件系统支持:
- Linux 内核 ≥ 2.6.22(推荐 ≥ 4.18)
- 文件系统需支持
O_DIRECT(如 ext4、xfs),且挂载时未禁用相关特性(如barrier=0可选,但需权衡数据安全性)
-
aio_write 默认关闭:写操作异步支持极弱,生产环境建议保持
aio_write off;
示例配置(放在 location 块内):
location /download/ {
root /data;
directio 4m;
aio on;
aio_write off;
output_buffers 1 128k;
sendfile off; # directio 与 sendfile 互斥
}注意:
sendfile on;和aio on;不能共存——sendfile走零拷贝路径,aio走io_submit+io_getevents路径,二者机制冲突。
为什么 events 块和 aio 没有关系
-
events块只管网络事件调度模型:比如use epoll;、worker_connections、multi_accept,它决定 Nginx 怎么高效收发 TCP 请求。 -
aio属于文件 I/O 层优化,发生在请求已进入处理阶段(比如读磁盘文件响应客户端)之后,和事件循环本身无关。 - Nginx 主循环始终是事件驱动的(epoll/kqueue),但默认文件读仍是同步阻塞调用;
aio是为绕过这一阻塞而提供的可选加速通道,仅限特定路径。
替代更可靠、更通用的异步方案
如果你追求真正灵活、低开销、适配大小 IO 的异步磁盘访问:
优先考虑
io_uring(Linux ≥ 5.1)
它原生支持 buffered/direct 模式,无需严格对齐,无 POSIX AIO 的线程池模拟缺陷,吞吐更高、延迟更稳。Nginx 尚未原生集成,但自研服务或 C++ 存储内核可直接使用liburing。Nginx 内置线程池(
thread_pool+aio threads=xxx)
更实用:把耗时的open()、stat()、read()等操作卸载到独立线程池,主线程不阻塞。适用于中小文件、混合业务场景,兼容性远好于aio on。
示例:
thread_pool default threads=16 max_queue=65536;
location /assets/ {
aio threads=default;
directio 0; # 关闭 directio,让线程池处理普通 read
}这个组合比硬凑 aio on + events 更稳定、更易调优。

















