NGINX 实现架构

高性能 Web 服务器 / 反向代理 — 核心架构全景

整体模块架构
NGINX Core 事件驱动 · 异步非阻塞 · 多进程 epoll / kqueue / eventport / select Master 进程 Worker 1 Worker N Worker 2 ··· ··· HTTP 模块 ngx_http_core_module proxy · rewrite · gzip · ssl Event 模块 ngx_events_module epoll · kqueue · select Mail 模块 ngx_mail_module imap · smtp · pop3 Stream 模块 ngx_stream_module TCP/UDP 代理 · 限速 其他 ngx_http_* third-party
请求处理流程
新连接到达 accept() 事件通知 epoll_wait() 读取请求数据 ngx_http_read _request_header 处理链执行 NGX_HTTP_ CONTENT_PHASE 等 发送响应 ngx_http_write ① 客户端 TCP 连接 ② 事件循环触发 ③ 解析 HTTP 头部 ④ 11 个处理阶段 ⑤ 写入 socket NGX_HTTP_POST_READ → SERVER_REWRITE → FIND_CONFIG → REWRITE → POST_REWRITE → PREACCESS → ACCESS → POST_ACCESS → TRY_FILES → CONTENT → LOG
Master-Worker 进程模型
Master 进程 root 权限运行 · 读取配置 · 管理 Worker 信号处理 (HUP/USR2/QUIT) · 绑定端口 Worker 1 Event Loop epoll_wait() 连接池 (数千连接) 每个连接内存仅 KB 级 Worker 2 Event Loop epoll_wait() 独立内存空间 进程间无需锁 Worker N Event Loop epoll_wait() CPU 亲和性绑定 worker_cpu_affinity Cache 进程 文件缓存加载 open_file_cache 共享内存通道 slab allocator fork() fork() fork() fork() 共享内存 (Shared Memory) — slab 分配器 · accept_mutex · SSL Session Cache · Limit Req Zone
内存与连接管理
内存池 (ngx_pool_t) 小块内存 链式 block 分配 默认页大小 4096B 大块内存 独立 malloc 分配 超出 pool size 时 清理回调链 (cleanup) 注册析构回调 · pool 销毁时自动调用 · 文件句柄关闭 核心特性 零碎片 · 无需 free · 请求结束时整体释放 · 极低分配开销 连接管理 (ngx_connection_t) 空闲连接池 freelist 链表管理 worker_connections 读写缓冲区 ngx_buf_t 链 sendfile 零拷贝 Keep-Alive 长连接复用 keepalive_timeout Upstream 后端连接池 keepalive 复用 每个连接仅需 ~2-4KB 内存 → 单 Worker 可支撑 10,000+ 并发连接
关键设计说明

🌐 事件驱动模型

NGINX 不使用线程处理每个连接,而是通过 epoll (Linux) / kqueue (BSD/macOS) 等系统调用实现异步 I/O 多路复用。一个 Worker 进程可同时处理数千个连接,内存开销极低。

⚡ 零拷贝 (Zero Copy)

使用 sendfile() 系统调用直接在内核空间将文件数据从磁盘发送到网卡,避免用户态缓冲区的数据拷贝,大幅提升静态文件传输性能。

🔄 热重载机制

Master 进程收到 SIGHUP 后重新读取配置,fork 新 Worker 进程并逐步接管旧连接,旧 Worker 在处理完存量请求后自动退出,实现零停机配置更新。

🧩 模块化设计

NGINX 的核心只负责事件调度和基础框架,所有功能(代理、缓存、压缩、SSL、限流等)都以模块形式挂载。HTTP 处理链由 11 个 Phase 按序执行,各 Phase 可注册多个 handler。

🧠 内存池管理

每个请求创建独立内存池,所有内存从池中分配,请求结束时整体释放。消除了内存碎片和内存泄漏问题,分配开销近似于栈分配。

📊 Slab 分配器

共享内存使用 slab 分配器管理,将内存页按固定大小(8B/16B/32B/...)划分为 slab,避免小块内存的碎片问题。用于共享数据如 limit_req 计数器、SSL session 等。