nginx通过事件驱动复用连接实现高并发:客户端连接靠keepalive+超时管理,上游连接靠keepalive池+事件调度,配合tcp探活与内存池复用,零分配开销。

Nginx 的异步事件驱动模型不是靠“多开连接”来扛并发,而是靠精准、低开销地复用已有连接——尤其是客户端连接和上游连接。这种复用不依赖线程等待或定时轮询,而是由事件系统实时驱动,在连接空闲、就绪或异常时自动调度。
客户端连接复用:靠 keepalive + 事件超时管理
浏览器发起的 HTTP/1.1 请求默认启用 Connection: keep-alive,Nginx 利用这一点维持 TCP 连接,避免重复握手:
-
keepalive_timeout 设置连接空闲后保留在 worker 中的最大时间(如
keepalive_timeout 75;),超时由红黑树定时器事件触发关闭,不占用额外线程 -
keepalive_requests 控制单个连接最多处理多少请求(如
keepalive_requests 1000;),达到上限后主动关闭,防止长连接累积状态泄漏 - 连接处于 idle 状态时,不消耗 CPU;epoll 仅在有新数据到达或超时事件触发时才唤醒处理,真正实现“无事不扰”
上游连接池复用:事件驱动的空闲连接调度
与后端服务(如应用服务器)的连接复用,是 Nginx 反向代理高效的关键。它不靠后台线程维护,而靠事件循环直接监听:
-
upstream 中配置 keepalive N(如
keepalive 32;),表示每个 worker 最多缓存 N 个空闲长连接,这些连接在首次使用后进入事件监听队列 - 当新请求到来,Nginx 从池中取出一个空闲连接,注册 write event;若发送缓冲区满或后端未响应,则挂起,转而处理其他就绪事件
- 连接空闲时,epoll 持续监听其可读状态;一旦后端返回响应或连接关闭,事件立即触发 cleanup 或复用逻辑,无需轮询扫描
连接失效的主动清理:TCP 层与应用层协同
后端可能静默断连,Nginx 不被动等待错误发生,而是通过多层事件机制提前感知:
- proxy_socket_keepalive on 启用内核 TCP keepalive 探测,空闲时发探测包;收到 RST 或超时后,事件循环立刻标记连接失效并移出池
- keepalive_timeout 设为略小于后端实际超时值(例如后端设 90s,Nginx 设 60s),确保在后端关闭前主动释放,避免复用已断连接
- proxy_next_upstream error timeout http_502 在首次复用失败时,事件驱动立即切换连接或重试,而不是阻塞等待
内存与连接结构复用:零分配开销支撑高频复用
连接复用效率不仅体现在网络层,更扎根于内存管理:
- 所有连接对象(
ngx_connection_t)从预分配的连接池中获取,worker 启动时一次性 malloc,运行中只复用不释放 - HTTP 请求上下文、buffer、headers 均来自 slab 内存池,避免频繁申请释放带来的锁竞争和碎片
- 每个连接的状态(如“等待请求头”“正在转发”“等待后端响应”)由状态机记录,事件触发时直接跳转下一阶段,无冗余初始化











