Nginx 核心架构:Master-Worker、epoll、热重载深度解析

一、前言

Nginx 是目前最流行的反向代理和 Web 服务器软件,在高并发场景下表现优异。本文从底层架构入手,带你理解 Nginx 为什么快、怎么工作,以及如何通过实操验证这些原理。

本文是 Nginx 系列学习的第一篇,基于 Rocky Linux 8.10 + Nginx 1.14.1 环境。


二、Nginx 架构总览

Nginx 采用 Master-Worker 多进程架构,这是它高性能的基石:

复制代码
┌─────────────────────────────────────┐
│            Master 进程               │
│   PID=169242                        │
│   职责:读取配置、fork Worker、      │
│         信号管理、平滑升级           │
└──────────┬──────────────────────────┘
           │ fork
     ┌─────┼─────┐
     ▼     ▼     ▼
┌────────┐ ┌────────┐ ┌────────┐
│Worker 1│ │Worker 2│ │Worker N│
│epoll  │ │epoll  │ │epoll  │
│处理请求│ │处理请求│ │处理请求│
└────────┘ └────────┘ └────────┘

核心组件

组件 数量 职责
Master 1 个 读取配置、管理 Worker、信号处理
Worker 通常 = CPU 核数 处理客户端请求,每个 Worker 独立运行
Cache Loader 可选 加载缓存元数据
Cache Manager 可选 管理缓存过期

三、关键配置项

复制代码
# /etc/nginx/nginx.conf
worker_processes  auto;             # 自动等于 CPU 核数
worker_rlimit_nofile 65535;         # 每个 Worker 最大文件描述符
​
events {
    use epoll;                      # 事件驱动模型(Linux 最佳选择)
    worker_connections  65535;      # 每个 Worker 最大连接数
    multi_accept on;                # 一次 accept 多个连接
    accept_mutex on;                # 避免惊群(默认开启)
}

配置项说明

配置项 作用 建议值
worker_processes auto Worker 数量自动等于 CPU 逻辑核数 autoCPU 核数
worker_connections 每个 Worker 最大并发连接数 65535
use epoll Linux 下最高效的事件驱动模型 epoll(Linux 3.9+)
multi_accept on 一次 accept 多个连接,减少系统调用 on
accept_mutex on 避免惊群,多个 Worker 轮流 accept on(默认)

四、实操验证

验证 1:Master-Worker 进程结构

复制代码
# 查看 Nginx 进程树
ps -ef | grep nginx
​
# 输出示例:
# root     169242      1  0  Jul28 ?  00:00:00 nginx: master process /usr/sbin/nginx
# nginx    176131 169242  0  Jul28 ?  00:00:00 nginx: worker process
# nginx    176132 169242  0  Jul28 ?  00:00:00 nginx: worker process

可以看到:1 个 Master(PID 169242),2 个 Worker(PID 176131/176132)。

验证 2:Worker 自动恢复

复制代码
# 杀死一个 Worker
kill -9 176131
​
# 查看进程树(1 秒后)
ps -ef | grep nginx
# root     169242      1  0  Jul28 ?  00:00:00 nginx: master process
# nginx    176132 169242  0  Jul28 ?  00:00:00 nginx: worker process
# nginx    177893 169242  0  Jul28 ?  00:00:00 nginx: worker process  ← 新 fork 的!

结论: Master 会在 1 秒内自动 fork 新的 Worker 替代死掉的 Worker,保证服务不中断。

验证 3:热重载(Hot Reload)原理

复制代码
# 修改配置后执行 reload
nginx -s reload

热重载过程:

复制代码
旧 Master(PID=169242)
  │
  ├── 读取新配置
  ├── fork 新 Worker(PID=178000, 178001)
  │
  ├── 发送 SIGQUIT 给旧 Worker
  │     ├── 旧 Worker 停止 accept(从 epoll 中移除 listen fd)
  │     ├── 处理中的活跃连接 → 继续处理,等完成后退出
  │     ├── 空闲 keepalive 连接 → 立即关闭
  │     └── 所有连接处理完毕 → Worker 退出
  │
  └── 新 Worker 开始处理新请求(这块是fork出新worker后就开始处理新请求,而不是等旧worker退出)

验证方法:

复制代码
# 创建一个长连接
python3 -c "
import socket, time
s = socket.socket()
s.connect(('127.0.0.1', 8080))
print('连接已建立')
time.sleep(30)  # 保持连接
" &
​
# 在长连接存活期间执行 reload
nginx -s reload
​
# 观察旧 Worker 状态(进入 FIN-WAIT-2)
ss -tlnp | grep 8080

验证 4:epoll vs select 性能对比

模拟场景: 服务器有 10000 个连接,其中只有 3 个活跃。

复制代码
# epoll_vs_select.py 核心逻辑
def select_model():
    # O(n):每次遍历 10000 个 fd
    return TOTAL_CONNECTIONS * 0.27  # 10000 × 0.27 = 2700
​
def epoll_model():
    # O(1):只返回 3 个活跃事件
    return ACTIVE_CONNECTIONS * 0.1  # 3 × 0.1 = 0.3

运行结果:

复制代码
select 每次循环开销: 2700.0 单位
epoll  每次循环开销: 0.3 单位
epoll 比 select 快: 9000 倍
​
并发连接数对性能的影响:
  连接数   select开销    epoll开销    比例
     100         27.0         0.3     90x
   1,000        270.0         0.3    900x
  10,000      2,700.0         0.3  9,000x
 100,000     27,000.0         0.3 90,000x

结论: epoll 的性能与总连接数无关,只与活跃连接数有关。select 的性能与总连接数成正比,连接越多越慢。


五、关键知识点总结

1. 为什么 Nginx 比 Apache 快?

对比项 Apache Nginx
架构 多进程/多线程(每个连接一个进程/线程) 事件驱动(单进程处理多连接)
内存 每个连接 ~2MB 每个连接 ~2.5KB
并发 几千连接 几万连接
静态文件 一般 极快(sendfile 零拷贝)

2. 惊群问题(Thundering Herd)

当多个 Worker 都监听同一个 socket 时,新连接到达会唤醒所有 Worker,但只有一个能 accept 成功,其他 Worker 白白被唤醒。

Nginx 的解决方案: accept_mutex

  • 所有 Worker 竞争 accept_mutex

  • 竞争成功的 Worker 开始 accept 新连接

  • 竞争失败的 Worker 回到 epoll_wait 等待

  • 配合 multi_accept on,一次 accept 多个连接,减少竞争频率

3. 为什么新连接不是由 Master 分配?

如果 Master 负责分配连接,Master 会成为瓶颈:

  • 所有新连接都要经过 Master → 单点瓶颈

  • 需要额外的 IPC 通信 → 延迟增加

  • Master 的 epoll 实例会成为热点

Nginx 的设计: 每个 Worker 独立 epoll 实例,直接 accept,互不依赖,完全并行。


六、F5 工程师看 Nginx 架构

复制代码
F5 概念                Nginx 对应
────────────────────────────────────
TMM(Traffic Management Microkernel) → Worker 进程
SCCP(Symmetric Control Plane)       → Master 进程
硬件加速(ASIC/FPGA)                  → epoll 事件驱动
FastL4 Profile                        → stream 模块(四层)
Client/Server SSL Profile             → http 模块(七层)

核心区别: F5 用硬件做加速,Nginx 用软件(epoll + 零拷贝)达到接近硬件的高性能。


七、生产建议

  1. Worker 数量 = CPU 核数 (或 auto),不要超过物理核数,否则上下文切换反而降低性能

  2. worker_rlimit_nofile 要设大 ,因为 max connection = worker_processes × worker_connections

  3. accept_mutex 默认开启,不要关闭,除非你能确认没有惊群问题

  4. multi_accept on 建议开启,减少 accept 竞争频率

  5. 热重载是安全的,旧 Worker 会优雅处理完所有活跃连接再退出


下一篇: Nginx 虚拟主机与 server_name 匹配规则详解

相关推荐
天空属于哈夫克31 天前
企业微信二次开发:精准实现关键词自动回复
架构·企业微信
虎头金猫1 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
还是大剑师兰特1 天前
解决nginx错误:http://localhost:7000正常,http://localhost:7000/map 报错404
nginx·大剑师
晨米酱1 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
这个DBA有点耶1 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
AI职业加油站1 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
码流子2 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
此冬歌咏2 天前
K8s 节点故障实战:优雅驱逐 31 秒,硬故障 331 秒,以及那个永远 Pending 的 Pod
运维·k8s
moMo2 天前
从固定流程到问题路由:让 LangGraph RAG 按需检索
架构
xing-xing2 天前
Docker容器中Nginx站点根目录网页配置访问
nginx·docker