Nginx 不使用红黑树管理活跃连接,epoll 内核中红黑树仅用于高效维护监听fd集合,就绪事件通过双向链表(就绪队列)O(1)返回;Nginx仅调用epoll_wait获取就绪列表并遍历处理。

Nginx 并不使用红黑树来管理活跃连接,也不依赖红黑树实现 epoll 的事件检索。
epoll 本身不依赖红黑树管理活跃连接
Linux 内核中,epoll 在内核态维护两个核心数据结构:
- 红黑树(rb-tree):用于存储所有被监听的文件描述符(fd),支持快速插入、删除和查找——这是为了高效管理“要监听哪些 fd”,而非“哪些 fd 就绪了”;
-
就绪队列(ready list,通常是双向链表):当某个 fd 发生事件(如可读、可写),内核将其节点加入该队列;
epoll_wait()直接从此队列取数据,时间复杂度为 O(1) 到 O(n),与监听总数无关。
Nginx 使用 epoll 但未干预其内部结构
Nginx 是 epoll 的用户态使用者,它:
- 调用
epoll_ctl()添加/修改/删除监听 fd(内核用红黑树维护这些注册项); - 调用
epoll_wait()获取就绪事件列表(内核从就绪队列批量拷贝到用户空间); - 对返回的就绪事件进行遍历处理,用的是简单的数组或链表(如
ngx_connection_t *数组),不涉及红黑树操作。
为什么红黑树常被误传为“管理活跃连接”?
混淆主要来自两点:
- 内核确实在 epoll 实现中用红黑树管理“监听集合”,但该结构只在注册/注销 fd 时起作用,运行时与事件分发无关;
- Nginx 自身连接池(
ngx_cycle_t → connections)用的是预分配数组 + 空闲链表,不是红黑树;它的定时器管理(如延迟关闭、超时)才用红黑树(ngx_timer_wheel或ngx_event_timer_rbtree),但这和 epoll 活跃连接检索完全独立。
真正决定 Nginx 高效的关键点
高效源于整体设计协同,而非某一个算法:
- epoll 的就绪队列机制,避免遍历全部监听 fd;
- Nginx 采用单线程多路复用 + 固定大小连接池,减少内存分配开销;
- 事件回调驱动,无阻塞 I/O,连接状态由内存变量直接记录;
- 定时器用红黑树优化超时管理,但这是另一条路径,不参与 I/O 事件分发主流程。
简言之:epoll 用红黑树管“要听谁”,用链表记“谁已说话”;Nginx 只负责“听到了就去办”,中间不插手内核的数据结构。把红黑树等同于“活跃连接管理”是一种常见误解。

















