nginx通过异步非阻塞事件驱动架构实现高并发:单worker进程基于epoll等i/o多路复用运行事件循环,全程non-blocking socket操作,红黑树管理超时,连接池与slab内存复用,多worker无锁协作。

Nginx 采用异步、非阻塞、事件驱动的架构,是它能高效处理数万甚至数十万并发连接的核心原因。关键不在于“多线程”或“多进程”的数量,而在于如何用极少的资源(通常是单个 worker 进程)持续轮询、响应和调度大量活跃连接。
事件循环:单 worker 的核心引擎
每个 Nginx worker 进程启动后,会进入一个紧凑的事件循环(event loop)。它不为每个连接创建新线程,也不等待某次读写完成才处理下一个请求。而是通过操作系统提供的高效 I/O 多路复用机制(如 epoll(Linux)、kqueue(FreeBSD/macOS)、evport(Solaris)),一次性监听成千上万个 socket 的可读/可写状态。
当内核通知“某个连接有数据到达”或“某个连接的发送缓冲区空了”,事件循环立刻调用对应的回调函数——比如解析 HTTP 请求头、读取请求体、查找静态文件、转发给 upstream、组装响应等——整个过程都在用户态内存中快速完成,无上下文切换开销。
连接生命周期全程非阻塞
从 accept 新连接开始,到最终 close,Nginx 对每个 socket 都设置为 non-blocking 模式:
- accept() 不阻塞:一旦监听 socket 就绪,就尽最大可能 accept 所有已排队的连接(避免惊群且减少延迟);
- recv() 不阻塞:读取时若无数据立即返回 EAGAIN/EWOULDBLOCK,转而处理其他就绪事件;
- send() 不阻塞:只尝试发送当前内核发送缓冲区允许的字节数,剩余数据挂起在连接的 output buffer 中,注册 write event 等下次可写再继续;
- 定时器与超时由红黑树管理:每个连接的 read/write timeout、keepalive timeout 都被统一纳入事件系统,无需独立线程轮询。
内存与连接复用降低开销
Nginx 预分配固定大小的连接池(由 worker_connections 指令控制),所有连接结构体(ngx_connection_t)在启动时一次分配、运行中复用,避免频繁 malloc/free;HTTP 请求解析使用 slab 分配器管理 request buffer,头部字段以指针方式引用原始内存,不拷贝字符串;keepalive 连接复用同一 socket 处理多个请求,省去三次握手、TLS 握手(若启用)等昂贵操作。
worker 进程协作与负载均衡
多个 worker 进程通过共享 listen socket(借助 accept_mutex 或 SO_REUSEPORT)分摊新连接接入压力;各 worker 独立运行事件循环,彼此无锁、无通信,仅通过共享内存(如 limit_req、limit_conn、upstream 状态)做轻量协同;CPU 绑定(worker_cpu_affinity)可进一步减少缓存抖动,提升 L1/L2 缓存命中率。
这套机制让 Nginx 在 C10K 乃至 C100K 场景下,仍保持低内存占用(每个空闲连接约 2–4 KB)、高吞吐(万级 RPS)、毫秒级延迟。本质是把“等待 I/O 完成”这个最耗时环节交给内核托管,自身始终处于“响应—处理—调度”的高速闭环中。











