Non-blocking IO使Nginx能以极轻量方式并发管理数万连接,核心是“不等、不占、不停”:调用recv()立即返回EAGAIN,靠epoll/kqueue事件驱动调度,避免线程切换与CPU空转,实现零线程开销、内存节省与响应稳定。

Non-blocking IO 不是让单次读写变快,而是让 Nginx 能用极轻量的方式同时盯住成千上万个连接,把 CPU 时间真正花在“干活”上,而不是空等。
核心逻辑:不等、不占、不停
传统阻塞模式下,一个连接读数据时,进程就卡在那里——就像服务员站在桌边等客人点菜,别的桌喊也听不见。Non-blocking IO 改变了这个状态:
- 调用 recv() 时,如果内核缓冲区没数据,立刻返回 EAGAIN/EWOULDBLOCK,而不是挂起进程;
- Nginx 把这个连接暂时放一边,转头去处理其他就绪的连接或新请求;
- 靠 epoll/kqueue 这类事件机制监听“什么时候有数据可读”,一触发就回来继续处理,全程不浪费 CPU 周期。
和事件循环怎么配合?
Non-blocking IO 本身只是“不阻塞”,真正发挥价值靠的是它和事件驱动模型的绑定:
- 每个 worker 进程运行一个事件循环,持续调用 epoll_wait()(Linux)或 kqueue()(BSD/macOS);
- 系统内核负责监控所有 socket 状态,只在“可读”“可写”“断连”等真实事件发生时才通知 Nginx;
- Nginx 收到通知后,才对对应连接执行非阻塞的 recv() 或 send(),一次读不完就再等下次通知——整个过程无等待、无线程切换、无资源闲置。
效率提升体现在哪?
不是单请求更快,而是整体吞吐和资源利用率跃升:
- 零线程开销:不用为每个连接分配栈空间、调度时间片,1 个 worker 可轻松扛住数万连接;
- 内存更省:每个连接只保留几十字节的 connection 结构体,而非完整线程上下文;
- 响应更稳:慢客户端上传、长轮询、HTTP/2 多路复用等场景下,不会拖垮其他请求;
- 抗抖动能力强:即使某次 I/O 操作延迟高(比如磁盘缓存未命中),也不会阻塞整个 worker 的事件调度。
注意:非阻塞 ≠ 万能
它的优势只在 I/O 层有效,一旦进入业务逻辑阶段,风险仍在:
- 在 Lua 模块里写死循环、调用 os.execute 或同步 DNS 查询,照样会卡住整个 worker;
- 复杂 JSON 解析、正则回溯、数据库直连等 CPU 或同步 I/O 操作,必须剥离到上游服务;
- Nginx 的职责边界很清晰:做好路由、协议处理、缓存、限流——把计算交给 FastAPI、Gin 或其他专用服务更安全高效。


















