Nginx worker 进程不参与内核级IO调度,仅通过epoll/kqueue事件驱动和sendfile零拷贝减少IO开销;静态文件响应速度取决于page cache命中率、sendfile启用、directio/aio配置及worker与磁盘的NUMA绑定。

Nginx 的 worker 进程在处理静态文件缓存时,并不直接参与传统意义上的“IO 调度”(如 Linux 内核的 CFQ、Deadline 或 BFQ 调度器),它本身不决定磁盘队列顺序或 I/O 优先级。真正起作用的是内核的块层调度机制和文件系统行为,而 Nginx worker 主要通过高效的 IO 模型(如 epoll/kqueue)和零拷贝技术来**减少 IO 开销、规避阻塞、提升吞吐**。
Worker 进程不调度磁盘 IO,只调度事件
Nginx worker 是单线程、事件驱动的。它把静态文件读取视为一个“可读事件”——当客户端请求一个已缓存的静态资源(比如 /static/logo.png),且该文件已在文件系统缓存(page cache)中时,worker 直接从内存 copy 到 socket buffer;若不在内存,则触发一次 page fault,由内核异步回填,worker 通常不会因此阻塞(得益于非阻塞 open/read + 异步通知)。这里没有“IO 请求排序”,只有“事件就绪通知”。
影响静态缓存响应速度的关键点
- 文件系统缓存命中率:频繁访问的静态文件应尽量常驻 page cache。可通过 vm.vfs_cache_pressure、vm.swappiness 等内核参数调优,避免热文件被轻易换出
- sendfile() 零拷贝启用:Nginx 默认开启 sendfile on;,绕过用户态缓冲区,直接由内核将 page cache 数据送入 socket,大幅降低 CPU 和内存拷贝开销
- directio 与 aio 的取舍:对大文件(如视频)且磁盘性能强(NVMe+XFS),可配 aio threads; + directio 4m; 绕过 page cache,避免污染缓存;但小文件禁用 directio,否则反而因缺少缓存而变慢
- worker 与磁盘绑定(可选):在多磁盘、多 NUMA 场景下,可用 worker_cpu_affinity 将特定 worker 绑定到靠近某块 SSD 的 CPU 核,缩短内存访问路径
缓存未命中时的真实 IO 路径
当请求的静态文件未在 page cache 中:
- worker 调用 openat()(非阻塞)获取 fd
- 调用 read() 或更常用 sendfile() —— 若数据不在内存,内核发起同步(或异步,取决于配置)磁盘读取,交由块设备队列调度
- 期间 worker 不等待,继续处理其他事件;待数据就绪(或 sendfile 完成),epoll 返回可写事件,worker 触发 TCP 发送
实用建议:让静态缓存 IO 更高效
- 确保 sendfile on;、tcp_nopush on;、tcp_nodelay on; 同时启用,配合使用
- 静态资源目录挂载时启用 noatime,避免每次读取更新访问时间戳带来的额外 IO
- 用 ionice -c2 -n0 nginx 适度提升 Nginx 进程的 IO 调度优先级(仅限有明确 IO 竞争时)
- 监控 cat /proc/sys/vm/stat_refresh 和 sar -B 观察 major page fault 和 %iowait,判断是否真受磁盘瓶颈限制

















