Nginx 的 Event Loop 是被动响应式事件驱动模型,依赖 epoll/kqueue 等内核机制通知就绪事件,通过非阻塞 I/O、状态机、连接池与红黑树定时器实现单 worker 高并发处理。

底层监听:靠 epoll/kqueue 等内核机制通知就绪
Linux 下默认启用 epoll(支持 ET 模式),worker 进程调用 epoll_wait() 进入休眠等待状态,直到内核告知哪些 socket 已就绪(如可读、可写、出错)。FreeBSD/macOS 用 kqueue,兜底方案才用低效的 select 或 poll。
监听始于 master 创建 listen socket,fork 后每个 worker 都调用 epoll_ctl(EPOLL_CTL_ADD) 把该 socket 加入自己的事件实例;新连接到来时,accept 出来的 client fd 也会立即注册进当前 worker 的 epoll 实例,关注 EPOLLIN。
事件分发:从就绪 fd 到具体 handler 的映射链
内核返回就绪事件列表后,Nginx 做三件事:
- 解析
ngx_event_t,提取 fd 和事件类型(read/write/error) - 通过 fd →
ngx_connection_t映射表,找到对应连接对象 - 按事件类型触发预设 handler:
– 监听 fd 可读 →ngx_event_accept执行 accept
– 客户端 fd 可读 →rev->handler,如ngx_http_process_request_line
– 客户端 fd 可写 →wev->handler,如ngx_http_writer
非阻塞 + 状态机:保障单线程不卡住
所有 socket 都设为非阻塞模式。一次 recv() 只取当前可用数据;send() 若返回 EAGAIN,就把剩余数据暂存 output buffer,并重新注册 EPOLLOUT 事件——等下次可写再继续发。整个请求生命周期由状态机驱动,handler 只处理当前阶段,不阻塞循环。
定时器(如连接超时、读体超时)由红黑树管理,Event Loop 每次迭代前检查是否到期,统一触发回调。
连接池与资源复用:降低事件调度开销
连接对象 ngx_connection_t 从预分配的连接池中获取,避免频繁 malloc/free;buffer 使用 slab 分配器 + chain 结构,小包高频场景下内存复用率高。这些设计让事件分发本身轻量,不成为瓶颈。


















