Nginx定时器是纯用户态实现,基于红黑树组织与主循环主动扫描:添加时标记类型、计算过期时间并插入红黑树;触发时由worker在ngx_process_events_and_timers中调用ngx_event_expire_timers遍历最小key节点执行超时处理。

nginx 的定时器事件不依赖内核,是纯用户态实现的自主超时控制机制,核心在于红黑树组织 + 单次循环中集中检查。
定时器事件怎么添加
添加本质是把一个 ngx_event_t 节点插入全局红黑树。关键步骤包括:
- 设置
ev->timer_set = 1标记该事件为定时器类型 - 计算过期时间点:
ev->timer.key = ngx_current_msec + timeout_ms - 调用
ngx_event_add_timer(ev, timeout_ms),内部完成红黑树插入 - 该节点随后被纳入 worker 进程的统一事件调度流程,无需额外注册或线程管理
触发时机与检查逻辑
定时器不是靠中断或信号唤醒,而是由每个 worker 在主循环中主动扫描:
- worker 每次执行
ngx_process_events_and_timers()时,都会调用ngx_event_expire_timers() - 该函数从红黑树根节点开始,持续取最小 key(即最早到期)的节点
- 若
node->key ,判定超时,执行其 <code>ev->handler - 重复此过程,直到首个未超时节点出现,即停止扫描
为什么选红黑树
红黑树在定时器场景下兼顾插入、删除和最小值查找效率:
- 添加新定时器:O(log n),比链表遍历快得多
- 删除已触发或取消的定时器:O(log n),支持任意节点移除
- 快速获取最近超时节点:O(1) 获取最小 key(红黑树最左节点)
- 避免每次遍历全部定时器,大幅降低高并发下的 CPU 开销
时间精度与更新机制
nginx 自维护当前毫秒时间,不频繁调用系统 syscall:
-
ngx_current_msec是 volatile 全局变量,由ngx_time_update()刷新 - 通常仅在 epoll_wait 返回时、且带
NGX_UPDATE_TIME标志才更新,减少系统调用次数 - 若配置了
timer_resolution,则启用定时器信号(如ITIMER_REAL),强制周期性更新时间并触发检查



















