Nginx采用多进程+异步非阻塞I/O模型,通过红黑树管理超时事件并结合epoll/kqueue timeout实现定时任务调度,不依赖系统级定时器。
Nginx 并没有传统意义上的“Event Loop”(如 Node.js 那样基于 JavaScript 单线程事件循环),它采用的是**多进程 + 异步非阻塞 I/O 模型**,其定时任务调度逻辑由核心的 event timer 机制驱动,底层依托操作系统提供的高效事件通知(epoll/kqueue/select)和红黑树管理的超时队列。
Nginx 将所有需要延后执行的操作(如连接超时、请求超时、keepalive 超时、worker 进程定期检查等)都抽象为 ngx_event_t 结构体中的 timer 属性。每个待调度任务被插入到一个全局红黑树(ngx_event_timer_rbtree)中,按超时时间排序。红黑树根节点始终指向最近将要触发的事件,实现 O(log n) 插入/删除 和 O(1) 获取最小超时时间。
ngx_process_events_and_timers() 时,先检查红黑树最小节点是否已超时handler 回调(如 ngx_event_expire_timers 处理连接超时)timerfd),而是靠 epoll_wait 的 timeout 参数控制等待时长——即「阻塞等待时间 = 最近 timer 到期剩余时间」模块开发者可通过 ngx_add_timer() 注册回调,本质上是初始化一个 ngx_event_t 并插入红黑树:
ngx_event_t 变量(通常作为模块静态变量或结构体内嵌)ev->handler = your_handler,并在 handler 中完成业务逻辑后调用 ngx_del_timer(ev) 或再次 ngx_add_timer(ev, delay) 实现周期性调度ev->timedout 或 ev->timer_set)Nginx 不使用 setitimer、timerfd_create 或 POSIX timers。它的「定时精度」取决于:
– epoll_wait/kqueue 的 timeout 参数(毫秒级)
– worker 进程是否繁忙(若 CPU 密集型操作过长,可能延迟响应 timer)
– 所有 timer 共享同一套机制,不存在独立线程或信号中断
keepalive_timeout 65,Nginx 会在客户端空闲时为该连接事件设置 65s 后触发的 timer;到期后调用 ngx_http_set_keepalive 关闭连接nginx-rtmp-module 的心跳检测、lua-nginx-module 的 ngx.timer.at(),底层也都映射到这套红黑树+epoll timeout 机制Nginx timer 是轻量、低开销的超时通知,设计目标是网络连接生命周期管理,不是通用任务调度器: