非阻塞i/o本身不缓存网页,而是通过协同page cache、sendfile和open_file_cache等机制实现高效静态资源分发:page cache提供零磁盘延迟响应,sendfile实现零拷贝,open_file_cache减少元数据开销,配合缓冲策略与事件驱动最大化性能。

非阻塞 I/O 本身不直接“缓存网页”,但它为静态资源的高效缓存与分发提供了底层支撑。真正起加速作用的是它与内核页缓存、sendfile、open_file_cache 等机制协同形成的低开销响应链——请求进来不等待,数据复用不读盘,元数据查询不重复。
page cache 是静态文件加速的第一层缓存
Nginx 处理 JS、CSS、图片等小静态文件时,默认走标准缓存 I/O 路径:内核先查 page cache;命中则立即返回,未命中才加载进内存并提供给 Nginx。这个过程对 Nginx 透明,但极为关键——非阻塞 I/O 只决定“何时去读”,而 page cache 决定“读什么、从哪读”。只要文件被访问过一次,后续请求大概率零磁盘延迟返回。
无需额外配置,Linux 文件系统默认启用 page cache,Nginx 默认受益于此。禁用 directio 是保障该机制生效的前提,否则会绕过缓存,反而增加磁盘压力。
sendfile 实现零拷贝直通,跳过用户态搬运
启用 sendfile on 后,Nginx 不再调用 read() + write(),而是让内核直接把 page cache 中的数据送入 socket 发送队列:
- 完全避开用户态内存,省去两次系统调用和两次数据拷贝
- 仍保持非阻塞语义:若 socket 缓冲区满,内核返回 EAGAIN,Nginx 自动将连接挂回可写事件队列,等通知再续传
- 要求文件是普通文件,且未启用 gzip、sub_filter 等需修改响应体的模块
open_file_cache 减少元数据开销,提升缓存命中稳定性
频繁 stat() 和 open() 会拖慢非阻塞效率。open_file_cache 缓存文件是否存在、是否可读、inode、大小等元数据,避免每个请求都穿透到磁盘:
- open_file_cache_valid 30s:每 30 秒检查一次缓存项有效性
- open_file_cache_min_uses 2:至少被访问 2 次才纳入缓存,过滤偶然请求
- open_file_cache_errors on:缓存“文件不存在”等错误结果,防扫描类请求反复打穿
搭配合适的 keys_zone 大小(如 10m)和 inactive 时间(如 60s),能让元数据查询从每次请求降为分钟级,显著降低内核路径争用。
缓冲策略与事件驱动放大非阻塞实际收益
非阻塞只是基础,真正释放性能靠整体协同:
- 读阶段采用试探性 recv():有数据就读,EAGAIN 就暂停,不轮询也不阻塞
- 写阶段依赖 sendfile 或缓冲链管理:响应数据积攒到合适大小或连接就绪时再发,减少系统调用频次
- multi_accept on + use epoll:单次事件通知批量处理多个连接,提升 CPU 利用率
- worker_connections 设至 10240 并匹配 ulimit -n,确保万级并发下事件槽位不成为瓶颈
这些配置不是孤立存在,它们共同让非阻塞 I/O 在静态服务中真正转化为更低延迟、更高吞吐和更稳响应。











