nginx 高并发下快速识别事件类型靠内核 epoll 就绪队列、预定义事件回调、红黑树超时管理及多 worker 隔离;epoll_wait 直接返回已分类就绪事件,避免轮询,结合连接状态与事件类型映射固定 handler,实现零猜测高效分发。

Nginx 在高并发下能快速识别事件类型,靠的不是逐个检查每个连接,而是把“谁发生了什么事”这个判断工作交给操作系统内核,并用高效的数据结构做索引和分发。
epoll 是识别事件类型的底层加速器
Linux 的 epoll 系统调用本身就在内核中维护一个就绪队列。当 socket 上发生可读(EPOLLIN)、可写(EPOLLOUT)或出错(EPOLLERR)等事件时,内核自动将对应 fd 和事件类型加入该队列。Nginx 调用 epoll_wait() 时,直接拿到已分类、已就绪的事件列表,无需遍历全部连接——这就跳过了传统轮询模型中最耗时的“猜哪个 socket 有事”环节。
事件类型映射到固定处理路径
Nginx 预定义了三类核心事件回调函数:
- 收到 EPOLLIN → 触发
ngx_http_process_request_line(读请求头)或ngx_http_read_client_request_body(读请求体) - 出现 EPOLLOUT → 调用
ngx_http_writer或ngx_http_upstream_handler(继续发送响应或转发数据) - 捕获 EPOLLERR 或 EPOLLHUP → 进入连接清理流程,如
ngx_http_close_connection
每个 socket 的 ngx_connection_t 结构里都存着当前状态(比如 read->ready 或 write->ready),事件循环拿到 fd 后,直接查表定位到对应连接对象,再根据事件类型调用绑定好的 handler,全程无分支猜测。
红黑树辅助超时与状态归类
除了 epoll 就绪事件,Nginx 还用红黑树统一管理所有连接的超时时间(如 send_timeout、client_header_timeout)。当 epoll_wait 返回空但最小超时已到,事件循环立刻从红黑树顶端取出过期连接,按其当前状态(等待读头?等待发响应?)触发对应超时处理逻辑——这也是一种“隐式事件类型识别”,不依赖 fd,而依赖时间维度的状态判定。
多 worker 下事件类型识别不冲突
master 进程不参与事件处理,只负责 fork 和信号转发。每个 worker 拥有独立的 epoll 实例和连接池,彼此之间不共享 fd 表或事件队列。即使上万连接同时活跃,每个 worker 只需专注自己那几千个 fd 的就绪状态,识别压力被水平摊薄。
基本上就这些。











