nginx 通过单 worker 进程内事件循环、非阻塞 i/o 和系统事件通知实现高效连接管理;连接复用、内存池、零拷贝及多 worker 协同进一步降低开销。

Nginx 的高效连接管理不靠堆线程或进程,而靠单 worker 进程内一个紧凑的事件循环,配合非阻塞 I/O 和操作系统级事件通知机制,把每个连接变成可调度、可暂停、可复用的轻量状态机。
事件循环是连接调度的核心
每个 worker 进程启动后进入无限循环,不轮询、不休眠,而是调用 epoll_wait(Linux)等系统调用,等待内核通知哪些 socket 就绪。一次调用就能获知成千上万个连接中哪些可读、可写或出错。收到就绪列表后,worker 立即遍历处理:接收请求头、转发给 upstream、组装响应、回写客户端——所有操作都在用户态内存中快速完成,不阻塞其他连接。
全程非阻塞,连接生命周期可控
从 accept 新连接开始,Nginx 就将 socket 设为 non-blocking 模式:
- accept() 会一次性拉取所有已排队连接,避免漏接或延迟
- recv() 若无数据立即返回 EAGAIN,转而处理别的就绪事件
- send() 只发当前缓冲区允许的字节数,剩余数据挂起并注册 write event,等下次可写再继续
- 超时控制(如 keepalive timeout、read/write timeout)由红黑树统一管理,无需独立线程扫描
连接与内存复用降低资源开销
连接不是临时创建再销毁,而是复用预分配的资源:
- worker_connections 指令设定连接池大小,所有 ngx_connection_t 结构体在启动时一次性分配、运行中反复复用
- HTTP 请求解析使用 slab 内存池管理 buffer,头部字段以指针引用原始内存,避免字符串拷贝
- keepalive 默认开启,同一 TCP 连接可承载多个 HTTP 请求,省去重复握手和 TLS 握手开销
- 静态文件响应通过 sendfile() 实现内核态零拷贝,跳过用户空间搬运
多 worker 协同,避免资源争抢
多个 worker 进程并非各自为政,而是通过机制协同分担负载:
- accept_mutex 控制新连接争抢,防止“惊群”;高并发下可设为 off,配合内核 SO_REUSEPORT 更高效
- multi_accept on 允许单次事件循环 accept 多个新连接,提升突发流量响应速度
- worker_processes 通常设为 CPU 核心数,避免过多进程争抢事件队列和缓存行
- upstream 连接池也由事件驱动管理:空闲连接被 epoll 监听,就绪即复用,错误即剔除,不依赖定时器轮询











