nginx非阻塞i/o核心在于“不等”:系统调用立即返回,无数据时返回eagain/ewouldblock;配合epoll/kqueue事件机制,仅在socket就绪时处理,避免忙等待,单worker可高效管理数万连接。

Nginx 的非阻塞 I/O 原理,核心在于“不等”——发起读写操作后立即返回,不因数据未就绪而停住进程。
非阻塞调用:系统调用立刻返回
当 Nginx 调用 recv() 或 send() 时,若内核缓冲区暂无数据可读、或无法立即写出,系统不会让进程挂起,而是立刻返回错误码(如 EAGAIN 或 EWOULDBLOCK)。此时进程仍处于运行态,可继续处理其他连接或任务。
配合事件机制:只在就绪时才真正操作
非阻塞本身不是魔法,它必须和事件通知机制结合才高效:
- Nginx 依赖操作系统提供的高性能事件接口(Linux 用 epoll,FreeBSD 用 kqueue)
- 这些接口能一次性监听成千上万个文件描述符(socket),并在某个 socket 有数据可读、可写或出错时,主动通知 Nginx
- Nginx 收到通知后,才对那个 socket 执行非阻塞的 recv/send,几乎总能成功,避免空轮询
与简单轮询的本质区别
非阻塞 ≠ 自己反复试:
- 如果不用 epoll/kqueue,仅靠循环调用 recv() 检查每个 socket,就是低效的“忙等待”,浪费 CPU
- Nginx 的做法是:把所有 socket 交给内核代为监控,自己只在真正有事时被唤醒——这是“事件驱动 + 非阻塞”的协同结果
- 一个 worker 进程因此能轻松管理数万连接,而内存和上下文切换开销极小
实际效果:连接多,但不增线程
比如一个 Nginx worker 处理 10,000 个活跃连接:
- 它不需要 10,000 个线程,也不需要 10,000 次阻塞等待
- 所有连接共用同一个事件循环,每次只处理当前就绪的几个 socket
- I/O 操作不卡主线程,CPU 时间始终用于有效工作,而非空等











