Nginx 事件驱动内核

反向代理/Web 服务器的主从进程模型 + epoll 事件循环 + 状态机 HTTP 处理。

概念

Nginx 用纯 C 编写 (约 16 万行),以高并发低内存著称。它的核心架构是一个 master 进程管理多个 worker 进程,每个 worker 是单线程 epoll 事件循环。与 Apache 的”每连接一线程/进程”模型不同,Nginx 的”worker = 单线程 + epoll”模型使得它在 C10K 问题下仍然能保持稳定。

核心组件

组件职责关键机制
Master 进程配置读取、worker 管理、信号处理fork worker
Worker 进程实际处理客户端连接单线程 epoll
epoll 事件循环非阻塞 I/O 多路复用EPOLLIN, EPOLLOUT
阶段状态机HTTP 请求分阶段处理11 个阶段
连接池预分配连接对象复用ngx_connection_t
共享内存worker 间共享数据slab 分配器
Upstream反向代理到后端服务器健康检查, 负载均衡

Master + Worker 进程模型

Master 进程 (root 启动, 绑定 80/443):
 fork()
 |
 +-- Worker 1: 监听共享 socket, epoll 处理请求
 +-- Worker 2: 监听共享 socket, epoll 处理请求
 +-- Worker 3: 监听共享 socket, epoll 处理请求
 +-- Worker N: 监听共享 socket, epoll 处理请求
 +-- Cache Manager: 缓存管理
 +-- Cache Loader: 缓存加载

 Master 职责:
 信号处理: SIGHUP (reload 配置), SIGUSR1 (重开日志)
 Worker 监控: worker 异常退出 → 重启新 worker
 配置更新: 新配置加载 → 新 worker 继承 → 旧 worker 优雅退出

epoll 事件循环

// Nginx 事件循环核心 (简化)
void ngx_process_events_and_timers(ngx_cycle_t *cycle) {
 for (;;) {
 // 1. 计算超时时间
 ngx_time_update();
 timer = ngx_event_find_timer();
 delta = ngx_current_msec;
 
 // 2. 调用 epoll_wait (或 kqueue)
 events = epoll_wait(epfd, event_list, NEVENT, timer);
 
 // 3. 处理就绪事件
 for (i = 0; i < events; i++) {
 rev = event_list[i].data.ptr; // ngx_connection_t
 if (event_list[i].events & EPOLLIN) {
 rev->handler(rev); // ngx_http_wait_request_handler
 }
 if (event_list[i].events & EPOLLOUT) {
 wev->handler(wev); // ngx_http_write_handler
 }
 }
 
 // 4. 处理到期定时器 (超时连接)
 ngx_event_expire_timers();
 
 // 5. 处理 posted events
 ngx_event_process_posted(cycle, &ngx_posted_accept_events);
 ngx_event_process_posted(cycle, &ngx_posted_events);
 }
}

HTTP 阶段处理

Nginx 将 HTTP 请求处理拆分为 11 个阶段 (phases):

请求生命周期:
 NGX_HTTP_POST_READ_PHASE
 ↓ (读取完请求头)
 NGX_HTTP_SERVER_REWRITE_PHASE (改写 URI, server 级别)
 ↓
 NGX_HTTP_FIND_CONFIG_PHASE (匹配 location)
 ↓
 NGX_HTTP_REWRITE_PHASE (改写 URI, location 级别)
 ↓
 NGX_HTTP_POST_REWRITE_PHASE (检查是否需重新匹配)
 ↓
 NGX_HTTP_PREACCESS_PHASE (访问限制预处理)
 ↓
 NGX_HTTP_ACCESS_PHASE (访问控制: allow/deny, auth)
 ↓
 NGX_HTTP_POST_ACCESS_PHASE (访问控制后处理)
 ↓
 NGX_HTTP_PRECONTENT_PHASE (生成内容前的最后钩子)
 ↓
 NGX_HTTP_CONTENT_PHASE (内容生成: proxy_pass, fastcgi, static)
 ↓
 NGX_HTTP_LOG_PHASE (日志记录)

每个阶段可注册多个 handler, 按顺序执行