Nginx采用多进程+单线程事件循环架构,每个worker进程基于epoll等系统调用异步处理数万并发连接,所有socket设为non-blocking模式,I/O等待转为事件注册与回调,避免阻塞和上下文切换。

Nginx 采用基于事件驱动的异步非阻塞模型,从根本上绕开了传统同步阻塞 I/O 在高并发场景下的性能瓶颈。它不为每个连接创建新进程或线程,而是用少量工作进程(通常与 CPU 核心数一致)持续轮询并响应多个客户端事件,从而实现高吞吐、低资源占用。
事件循环如何替代线程/进程模型
传统 Web 服务器(如 Apache 的 prefork 模式)为每个 HTTP 请求 fork 一个进程或启用一个线程,导致上下文切换开销大、内存占用高、连接数受限。Nginx 则让每个 worker 进程绑定一个事件循环(基于 epoll/kqueue/iocp 等高效系统调用),在单个线程内同时监听成千上万个 socket 的可读/可写状态。
- 一个 worker 进程可管理数万并发连接,所有连接共享同一套事件队列和回调逻辑
- 当某个 socket 准备就绪(例如收到请求头),事件循环立即触发对应 handler,无需等待 I/O 完成
- 整个过程不阻塞其他连接的处理,也不会因磁盘读写或 upstream 延迟而卡住整个进程
非阻塞 I/O 是事件循环的基础支撑
Nginx 所有 socket 均设为 non-blocking 模式。这意味着 read/write 系统调用不会挂起当前执行流,而是立刻返回:成功则处理数据;失败且 errno 为 EAGAIN/EWOULDBLOCK,则说明暂时无数据或缓冲区满,事件循环会继续处理其他就绪事件,并稍后重试。
- 例如接收请求体时,若只读到部分数据,Nginx 不会阻塞等待剩余字节,而是注册 EPOLLIN 事件,等下次就绪再续读
- 向客户端发送响应时,若 send() 返回 EAGAIN,它将该连接加入“写就绪等待队列”,避免忙等或丢包
- 这种细粒度控制使 I/O 操作完全融入事件流,消除传统阻塞调用带来的空转或资源锁死
多进程 + 单线程事件循环的协同设计
Nginx 并非纯单线程,而是 master-worker 多进程架构:master 进程负责配置加载、信号管理、worker 启停;每个 worker 进程独立运行自己的事件循环,彼此无锁、无共享内存(除 accept 锁等极少数同步点)。
- 通过 SO_REUSEPORT 或 Nginx 内置的 accept_mutex,避免多个 worker 同时争抢新连接(惊群问题)
- 每个 worker 的事件循环互不影响,故障隔离性好;CPU 密集型任务(如 SSL 握手、gzip 压缩)也尽量异步化或卸载到专用线程池(1.7.11+ 支持 thread pool)
- 这种分层让高并发下调度更轻量,也便于水平扩展至多核机器
与同步阻塞模型的关键差异点
同步阻塞模型中,“等待数据到达”和“等待写入完成”都是主动挂起当前执行路径的操作;而 Nginx 的事件循环始终处于“响应就绪事件”的活跃态,I/O 等待被转化为事件注册与回调触发,时间被用于处理真实业务,而非空等。
- 没有线程栈堆积,内存占用稳定(每个连接仅需 KB 级上下文)
- 无上下文切换抖动,尤其在 10K+ 并发时,CPU 缓存友好、延迟可控
- 超时、限速、重试等机制均基于事件定时器(timer wheel 实现),不依赖操作系统 sleep 或线程休眠










