非阻塞i/o是nginx高并发基石,通过o_nonblock使worker不阻塞、配合epoll/kqueue事件驱动实现高效复用;配置不当(如proxy_buffering off、同步auth_request等)会破坏其异步优势。

Non-blocking IO 是 Nginx 高并发能力的底层基石,它不靠堆线程或进程,而是让单个 worker 进程高效“伺候”成千上万连接——响应快、资源省、延迟稳。
非阻塞 I/O 怎么让 Nginx 不卡住
传统服务器(如 Apache prefork)为每个连接分配一个线程/进程,一旦请求要读磁盘或等后端响应,该线程就停在那儿干等,CPU 白白闲置。Nginx 完全不同:
- 所有 socket 都设为 O_NONBLOCK,调用
recv()或send()时,没数据或写不满就立刻返回EAGAIN,绝不等待; - worker 进程把空闲时间让出来,转头处理其他已就绪的连接;
- 等内核通知“数据到了”或“可以写了”,再回来继续处理——整个过程不阻塞、不浪费调度资源。
必须搭配事件驱动才能真正生效
非阻塞本身只是“不傻等”,但若靠轮询检查每个 socket 状态,CPU 就会空转。Nginx 的关键在于把它和 epoll(Linux)或 kqueue(BSD) 结合:
- epoll 在内核维护一个就绪队列,只在 socket 状态变化(如可读、可写)时通知 Nginx;
- Nginx 的事件循环拿到一批就绪 fd 后,挨个用非阻塞方式收发数据,直到返回
EAGAIN才切换下一个; - 这种组合把“查状态”和“做操作”彻底解耦,避免了无效系统调用和上下文切换。
配置不当会悄悄破坏非阻塞效果
有些看似合理的配置,实际会让 Nginx 回退到同步等待,拖慢整个事件循环:
-
proxy_buffering off+ 慢后端 → Nginx 被迫轮询等待响应,失去异步优势; -
auth_request直接调 HTTP 接口 → 默认同步阻塞等待鉴权结果,应改用本地 JWT 校验或配合auth_request_set缓存; - SSL 握手未启用
ssl_session_cache shared→ 每次新建连接都要完整 TLS 握手,几十毫秒耗在阻塞等待上; - 日志中大量使用
$request_time且磁盘写入慢 → 虽不直接阻塞网络 I/O,但可能间接影响 worker 调度节奏。
小文件服务特别受益于非阻塞 + 零拷贝
静态资源(JS/CSS/图片)这类小文件请求,高频、短平快,非阻塞 I/O 的价值尤为突出:
- 启用
sendfile on,让内核直接在 page cache 和 socket buffer 间搬运数据,跳过用户态内存拷贝; - 配合
tcp_nopush on,攒够 TCP 报文再发,减少小包数量; -
open_file_cache缓存文件句柄和元数据,避免每次请求都触发stat()系统调用; - 关闭不必要的
access_log,进一步削减内核路径开销。











