Nginx worker 进程采用基于 epoll 的同步事件驱动主循环,无传统 Event Loop 抽象;内核通知就绪事件后,封装为 ngx_event_t 入队并同步调用 handler,注册按需动态完成,定时器与清理任务统一纳入循环调度。

Nginx 中并没有一个传统意义上由 JavaScript 或 Node.js 那样的单线程主循环抽象出来的 “Event Loop”,而是每个 worker 进程内部运行一个自主控制、同步执行的事件驱动主循环,它直接依托操作系统提供的异步 I/O 机制(如 epoll)来响应和调度网络事件。
事件监听靠内核通知,不轮询
worker 进程启动后,持续调用 epoll_wait()(Linux 下)等待内核通知。内核只在 socket 真正就绪(如可读、可写、出错)时才返回事件,避免了 select/poll 的全量扫描开销。监听 socket 在初始化时注册读事件,新连接到达即触发 accept;客户端 socket 接入后,立即设为非阻塞,并注册 EPOLLIN 关注数据到达。
事件分发是“搬运+同步调用”两步走
- 内核返回就绪 fd 列表后,Nginx 不直接执行业务逻辑,而是把每个就绪事件封装成 ngx_event_t 结构体,填入内部就绪队列
- 随后遍历该队列,依次同步调用每个事件绑定的 handler 函数,比如:
– 监听 fd 就绪 → 执行 ngx_event_accept
– 客户端 fd 可读 → 执行 ngx_http_process_request_line
– 响应缓冲区就绪 → 执行 ngx_http_writer
事件注册按需动态完成
handler 不是一次性全局注册,而是随连接生命周期分阶段挂载:
- 监听 socket 初始化时注册 accept 处理函数
- accept 后为新连接注册读事件 handler(如解析请求行)
- 需要发送响应时,才为写事件注册 handler,并可能调用 epoll_ctl(EPOLL_CTL_MOD) 更新监听状态
- 所有注册都通过 ngx_event_t 统一管理,其中 handler 存函数指针,data 存连接或请求上下文
定时器与清理任务也纳入同一循环
超时管理(如连接空闲超时、请求体读取超时)由红黑树维护,EventLoop 每次迭代前检查是否到期;连接关闭、内存回收等清理动作也作为事件统一调度,无需额外线程或信号机制。整个流程无中断、无回调嵌套、无线程切换,全部在当前 worker 的单一执行流中完成。



















