架构分析
约 800 字大约 3 分钟
2025-08-28
默认配置下,工作进程数与 CPU 数相同,以提高 CPU 亲和性
信号
主进程与工作进程间通过频道(channel)通信,用于将控制工作进程的操作信号传递给工作进程
共享内存
Nginx 下的多个进程访问同一个内存地址,即实现了内存共享
进程调度
每个工作进程都继承了主进程的监听套接字,但同一时间一个请求只能由一个进程接收网络连接,因此需要使用通过调度使工作进程协同工作
- 无调度模式:当请求到来时,所有的工作进程都会被唤醒,尝试获取系统资源,例如最早拿到 CPU 资源的进程最有可能拿到请求的处理权
- 互斥锁模式:在
无调度模式中一个请求的到来却会唤醒所有的进程,对系统而言会是大量的性能消耗,这就是所谓的惊群现象。引入一个互斥锁(accept_mutex),每一个工作进程在负载较低的情况下会周期性地尝试获取这个锁,一旦工作线程获得了该锁,将自己的socket监听注入事件引擎接收外部连接事件 - 套接字分片:每个工作进程都有一组相同的监听套接字,当外部请求到来时,由内核决定哪个工作进程的套接字能够接收连接;因为由内核实现,性能最好
事件驱动
上文提到,工作线程的数量一般为 CPU core 的数量,那么为什么有限的进程如何处理大量的连接? Nginx 是事件驱动程序设计,等待事件到来时才响应。例如一个请求到来,需要将其转发至对应的应用程序,完成转发后该进程不会一直等待该请求的后续,而是已经完成这一「事件」,转而去处理其他事件 对于大量的连接,需要对这些连接进行监听,以保证在连接产生事件时能够使worker快速响应。因此 nginx 使用epoll模型
epoll 模型
I/O 多路复用
通过某种机制,使得一个线程同时监控多个I/O通道(连接),并在某个连接就绪时进行处理 Linux 中提供了三种复用模型:
- select:遍历内核中的所有
fd,检查是否有事件就绪,且最多支持 1024 监听数 - poll:与
select相似,但改进了监听数的限制 - epoll:使用红黑树管理
fd,增删查改O(log n)
为什么说 epoll 是最高效的
epoll 维护一个就绪列表,只关注就绪的连接事件 非阻塞:epoll 存在最大等待时间,超过等待时间后若连接还没有准备好数据,那么不会阻塞而是处理下一个连接,避免慢客户端导致长等待 
工作流程

