🏗️ Master-Worker 架构

┌─────────────────────────────────────────────────────────────────┐
│                         Master Process                          │
│                        (主进程 - 管理员)                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │ 读取配置    │  │ 管理 Worker │  │ 平滑重启    │             │
│  │ 验证配置    │  │ 进程状态    │  │ 热升级      │             │
│  └─────────────┘  └─────────────┘  └─────────────┘             │
└─────────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
              ▼               ▼               ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│   Worker Process │ │   Worker Process │ │   Worker Process │
│      (工作进程)   │ │      (工作进程)   │ │      (工作进程)   │
│  ┌────────────┐  │ │  ┌────────────┐  │ │  ┌────────────┐  │
│  │ Event Loop │  │ │  │ Event Loop │  │ │  │ Event Loop │  │
│  │ 事件循环    │  │ │  │ 事件循环    │  │ │  │ 事件循环    │  │
│  └─────┬──────┘  │ │  └─────┬──────┘  │ │  └─────┬──────┘  │
│        │         │ │        │         │ │        │         │
│  ┌─────▼──────┐  │ │  ┌─────▼──────┐  │ │  ┌─────▼──────┐  │
│  │ 处理连接   │  │ │  │ 处理连接   │  │ │  │ 处理连接   │  │
│  │ 处理请求   │  │ │  │ 处理请求   │  │ │  │ 处理请求   │  │
│  └────────────┘  │ │  └────────────┘  │ │  └────────────┘  │
└──────────────────┘ └──────────────────┘ └──────────────────┘
        │                    │                    │
        └────────────────────┼────────────────────┘
                             │
              ┌──────────────┴──────────────┐
              │              │              │
              ▼              ▼              ▼
         ┌────────┐    ┌────────┐    ┌────────┐
         │ 客户端 │    │ 后端   │    │ 文件系统│
         │ Clients│    │ Server │    │ Files  │
         └────────┘    └────────┘    └────────┘
                    
💡 架构特点:
  • Master 进程 - 不处理客户端请求,只负责管理职责
  • Worker 进程 - 对等关系,独立处理请求,无共享状态
  • 事件驱动 - 每个 Worker 使用异步非阻塞 I/O
  • 无锁设计 - 进程间无需锁,减少上下文切换

Master 进程职责

职责说明触发条件
读取和验证配置读取 nginx.conf 并验证语法启动/重载配置
绑定端口创建监听套接字启动/热升级
管理 Worker启动、停止、重启 Worker 进程启动/配置变更
平滑重启发送信号重新加载配置HUP 信号
热升级不中断服务升级 Nginx 二进制USR2 信号
日志轮转重新打开日志文件USR1 信号

Worker 进程职责

职责说明特点
处理连接接受并处理客户端连接异步非阻塞
执行模块逻辑运行 HTTP、Stream 等模块代码按配置执行
I/O 操作读写网络、文件系统事件驱动
缓存管理管理代理缓存、FastCGI 缓存进程内缓存
日志记录写入访问日志和错误日志缓冲写入

🔄 事件驱动模型

Worker 进程
启动
初始化
创建连接池
注册事件
监听套接字
事件循环
Event Loop
┌─────────┐     ┌──────────┐     ┌─────────┐     ┌─────────┐     ┌─────────┐
│  Client │     │ epoll    │     │ Worker  │     │ Backend │     │  File   │
│         │     │ (内核)   │     │         │     │ Server  │     │ System  │
└────┬────┘     └────┬─────┘     └────┬────┘     └────┬────┘     └────┬────┘
     │                │                │                │                │
     │ TCP Connect    │                │                │                │
     │───────────────>│                │                │                │
     │                │ EPOLLIN 事件   │                │                │
     │                │───────────────>│                │                │
     │                │                │                │                │
     │                │                │ accept()       │                │
     │                │                │ 接受连接       │                │
     │                │                │                │                │
     │ HTTP Request   │                │                │                │
     │───────────────>│                │                │                │
     │                │ EPOLLIN 事件   │                │                │
     │                │───────────────>│                │                │
     │                │                │                │                │
     │                │                │ 读取请求       │                │
     │                │                │ 解析头部       │                │
     │                │                │                │                │
     │                │                │ 匹配 location  │                │
     │                │                │                │                │
     │                │                │ proxy_pass     │                │
     │                │                │───────────────>│                │
     │                │                │                │                │
     │                │ EPOLLOUT 事件  │                │                │
     │                │<───────────────│                │                │
     │                │                │                │                │
     │                │                │ 读取后端响应   │                │
     │                │<───────────────│                │                │
     │                │                │                │                │
     │ HTTP Response  │                │                │                │
     │<───────────────│                │                │                │
     │                │                │                │                │
     │                │                │ 记录日志       │                │
     │                │                │ 关闭连接       │                │
     │                │                │                │                │
                    

事件处理流程

1. 事件注册

Worker 启动时,将监听套接字注册到事件多路复用器(epoll/kqueue)

2. 事件等待

调用 epoll_wait() 阻塞等待事件发生,超时时间由配置决定

3. 事件分发

事件发生后,根据文件描述符找到对应的连接和回调函数

4. 事件处理

执行回调函数处理请求,可能是读取、写入或关闭连接

5. 事件完成

处理完成后,可能注册新的事件(如写事件)或关闭连接

事件多路复用方法对比

方法 操作系统 性能 特点
epoll Linux 2.6+ 最优 红黑树存储,O(1) 事件查找,支持边缘触发
kqueue FreeBSD, macOS 优秀 BSD 系统原生,功能丰富
/dev/poll Solaris, AIX 良好 内核级轮询,性能稳定
poll 跨平台 一般 线性扫描,连接数多时性能下降
select 跨平台 较差 有文件描述符数量限制(通常 1024)
💡 配置建议:
# 自动选择最佳事件方法
events {
    use epoll;  # Linux 下推荐显式指定
    
    # 每个 Worker 的最大连接数
    worker_connections 10240;
    
    # 接受多个连接
    multi_accept on;
    
    # 使用互斥锁(高并发时建议关闭)
    accept_mutex off;
}

🧩 模块系统架构

┌─────────────────────────────────────────────────────────────┐
│              Nginx 模块系统架构图                            │
└─────────────────────────────────────────────────────────────┘

【核心模块 Core Modules】(必选,无法禁用)
├── ngx_core_module          (核心配置)
├── ngx_errlog_module        (错误日志)
├── ngx_conf_module          (配置解析)
├── ngx_events_module        (事件处理)
├── ngx_event_core_module    (事件核心)
├── ngx_regex_module         (正则表达式)
└── ngx_openssl_module       (SSL/TLS 支持)

【HTTP 模块 HTTP Modules】
├── 标准模块 (默认编译)
│   ├── ngx_http_core_module         (HTTP 核心)
│   ├── ngx_http_upstream_module     (负载均衡)
│   ├── ngx_http_proxy_module        (反向代理)
│   ├── ngx_http_fastcgi_module      (FastCGI)
│   ├── ngx_http_gzip_module         (压缩)
│   ├── ngx_http_ssl_module          (HTTPS)
│   ├── ngx_http_v2_module           (HTTP/2)
│   ├── ngx_http_v3_module           (HTTP/3)
│   ├── ngx_http_limit_req_module    (请求限流)
│   ├── ngx_http_limit_conn_module   (连接限制)
│   ├── ngx_http_auth_basic_module   (基本认证)
│   ├── ngx_http_rewrite_module      (URL 重写)
│   └── ngx_http_log_module          (访问日志)
│
└── 可选模块 (需编译时启用)
    ├── ngx_http_stub_status_module      (状态监控)
    ├── ngx_http_sub_module              (内容替换)
    ├── ngx_http_dav_module              (WebDAV)
    ├── ngx_http_geoip_module            (GeoIP)
    ├── ngx_http_lua_module              (Lua 脚本) ★
    └── ngx_http_cache_purge_module      (缓存清除) ★

【邮件代理模块 Mail Modules】
├── ngx_mail_core_module
├── ngx_mail_smtp_module
├── ngx_mail_pop3_module
├── ngx_mail_imap_module
└── ngx_mail_ssl_module

【TCP/UDP代理模块 Stream Modules】
├── ngx_stream_core_module
├── ngx_stream_proxy_module
├── ngx_stream_ssl_module
└── ngx_stream_upstream_module

★ 第三方模块

模块类型与处理阶段

模块类型 处理阶段 典型模块 指令示例
配置模块 启动时 ngx_core_module worker_processes
事件模块 运行时 ngx_event_core_module worker_connections
处理阶段模块 请求处理 ngx_http_access_module allow, deny
内容生成模块 CONTENT 阶段 ngx_http_proxy_module proxy_pass
过滤器模块 响应输出 ngx_http_gzip_module gzip
负载均衡模块 上游选择 ngx_http_upstream_module upstream
📦 模块查看方法:
# 查看已编译的模块
nginx -V

# 输出示例
nginx version: nginx/1.24.0
built by gcc ...
configure arguments: --with-http_ssl_module --with-http_v2_module ...

⚡ 高性能设计原理

多进程 vs 多线程模型对比

特性 Nginx (多进程) 传统服务器 (多线程)
进程/线程关系 Worker 进程相互独立 线程共享进程资源
锁竞争 无需锁(无共享状态) 需要互斥锁保护共享资源
故障隔离 单个 Worker 崩溃不影响其他 线程崩溃可能导致整个进程崩溃
内存使用 进程间内存独立 线程共享内存空间
扩展性 多核 CPU 友好 受 GIL 等限制
调试难度 相对简单 死锁、竞态条件复杂

内存池设计

┌─────────────────────────────────────────────────────────────┐ │ Nginx 内存池结构 │ ├─────────────────────────────────────────────────────────────┤ │ ngx_pool_t (内存池头) │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ d = ngx_pool_data_t │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ 已分配内存块 1 (ngx_pool_large_t) │ │ │ │ │ │ - 大内存分配(> 4KB)链表 │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ 已分配内存块 2 │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ current ──> 当前小块分配位置 │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ ████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ │ │ │ │ 已使用 空闲空间 │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ max = 4096 bytes (单次分配上限) │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ cleanup ──> 清理回调函数链表 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ cleanup handler: close_file │ │ │ │ cleanup handler: free_memory │ │ │ │ cleanup handler: destroy_temp_file │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ 内存分配策略: ├── 小内存 (≤ 4KB): 从 pool->d.current 分配,指针移动 └── 大内存 (> 4KB): 单独分配,加入 large 链表

零拷贝技术

技术 系统调用 数据拷贝次数 说明
传统 I/O read + write 4 次拷贝 磁盘→内核→用户→内核→网卡
mmap mmap + write 3 次拷贝 内存映射减少一次拷贝
sendfile sendfile 2 次拷贝 内核态直接传输
sendfile + TCP_CORK sendfile + setsockopt 2 次拷贝 延迟发送,合并小包
💡 零拷贝配置:
http {
    # 启用 sendfile 零拷贝
    sendfile on;
    
    # 启用 tcp_nopush,配合 sendfile 使用
    tcp_nopush on;
    
    # 启用 tcp_nodelay,禁用 Nagle 算法
    tcp_nodelay on;
    
    # sendfile 单次最大传输量
    sendfile_max_chunk 2m;
}

🔗 连接处理机制

┌─────────┐     ┌──────────┐     ┌─────────┐     ┌─────────┐
│  Client │     │  Listen  │     │ Worker  │     │  Free   │
│         │     │  Socket  │     │  Pool   │     │  List   │
└────┬────┘     └────┬─────┘     └────┬────┘     └────┬────┘
     │                │                │                │
     │ SYN            │                │                │
     │───────────────>│                │                │
     │                │                │                │
     │ SYN-ACK        │                │                │
     │<───────────────│                │                │
     │                │                │                │
     │ ACK            │                │                │
     │───────────────>│                │                │
     │                │                │                │
     │                │ accept()       │                │
     │                │───────────────>│                │
     │                │                │                │
     │                │                │ 从空闲链表获取 │
     │                │                │ ngx_connection │
     │                │                │───────────────>│
     │                │                │                │
     │                │                │ 初始化连接     │
     │                │                │ - 设置回调     │
     │                │                │ - 注册读事件   │
     │                │                │                │
     │ HTTP Request   │                │                │
     │───────────────>│                │                │
     │                │                │                │
     │                │ 读事件触发     │                │
     │                │───────────────>│                │
     │                │                │                │
     │                │                │ 读取并解析请求 │
     │                │                │                │
     │                │                │ 处理请求       │
     │                │                │                │
     │ HTTP Response  │                │                │
     │<───────────────│                │                │
     │                │                │                │
     │                │                │ 连接回收       │
     │                │                │ (keepalive)    │
     │                │                │                │
                    

连接状态流转

FREE
空闲状态
ACCEPT
接受连接
READ
读取请求
PROCESS
处理请求
WRITE
写入响应
KEEPALIVE
保持连接
FREE
回收到空闲链表

连接池配置

指令 默认值 说明 调优建议
worker_connections 1024 每个 Worker 最大连接数 根据内存和负载调整,建议 10240+
worker_rlimit_nofile - Worker 最大文件描述符 应 ≥ worker_connections × 2
keepalive_timeout 75s 长连接超时 根据业务调整,API 可设短些
keepalive_requests 100 长连接最大请求数 建议 1000+ 减少握手
keepalive_time 长连接最大使用时间 1.19.10+ 新增,防止连接老化

📊 配置加载与热更新

Master
接收信号
读取配置
nginx.conf
验证配置
语法检查
成功?
通知 Worker
发送信号
Worker 重启
平滑过渡

信号处理

信号 发送给 作用 命令示例
HUP Master 重新加载配置 nginx -s reload
USR1 Master 重新打开日志文件(日志轮转) kill -USR1 $(cat nginx.pid)
USR2 Master 热升级(启动新 Master) kill -USR2 $(cat nginx.pid)
WINCH Master 优雅关闭 Worker(升级后) kill -WINCH $(cat nginx.pid.oldbin)
TERM Master/Worker 快速关闭 nginx -s stop
QUIT Master/Worker 优雅关闭(完成当前请求) nginx -s quit
🔄 热升级流程:
# 1. 备份旧二进制
sudo cp /usr/sbin/nginx /usr/sbin/nginx.old

# 2. 替换新二进制
sudo cp nginx-new /usr/sbin/nginx

# 3. 发送 USR2 信号,启动新 Master
sudo kill -USR2 $(cat /var/run/nginx.pid)

# 4. 验证新版本
ps aux | grep nginx

# 5. 优雅关闭旧 Worker
sudo kill -WINCH $(cat /var/run/nginx.pid.oldbin)

# 6. 确认无误后关闭旧 Master
sudo kill -QUIT $(cat /var/run/nginx.pid.oldbin)

# 如需回滚
sudo kill -USR2 $(cat /var/run/nginx.pid)
sudo kill -WINCH $(cat /var/run/nginx.pid.oldbin)

📈 性能调优参数

核心参数配置

参数类别 指令 推荐值 说明
进程配置 worker_processes auto 自动检测 CPU 核心数
worker_rlimit_nofile 65535 最大文件打开数
worker_connections 10240-65535 每 Worker 连接数
网络优化 sendfile on 启用零拷贝
tcp_nopush on TCP 包优化
tcp_nodelay on 禁用 Nagle 算法
keepalive_timeout 65s 长连接超时
缓存优化 open_file_cache max=10000 inactive=20s 文件缓存
open_file_cache_valid 60s 缓存检查间隔
open_file_cache_min_uses 2 最小使用次数
缓冲优化 client_body_buffer_size 16k-128k 请求体缓冲
proxy_buffer_size 8k-16k 代理响应头缓冲
💡 完整优化配置示例:
# 进程配置
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
    accept_mutex off;
}

http {
    # 基础优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    # 连接优化
    keepalive_timeout 65;
    keepalive_requests 1000;
    keepalive_time 1h;
    
    # 文件缓存
    open_file_cache max=10000 inactive=20s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 2;
    
    # 缓冲配置
    client_body_buffer_size 128k;
    client_max_body_size 100m;
    
    # 代理缓冲
    proxy_buffer_size 16k;
    proxy_buffers 8 32k;
    proxy_busy_buffers_size 64k;
}