nginx worker进程连接复用本质是两级独立机制:前端通过预分配ngx_connection_t结构体池(固定数组+free_connections链表)复用元数据,后端通过per-server lru socket缓存队列(由keepalive指令限制)复用空闲连接,二者均依赖状态重置与定时清理而非动态创建销毁。

Nginx 的 Worker Process 处理连接池复用,本质是两级复用:前端连接靠预分配结构体复用,后端连接靠 keepalive 缓存 socket 复用。两者独立运行、协同工作,不依赖动态创建销毁,而是靠固定池 + 状态重置 + 定时清理实现高性能。
Worker 内部连接结构体池:固定数组 + 链表管理
每个 Worker 进程启动时就一次性分配好 worker_connections 个 ngx_connection_t 结构体,组成静态数组。这些结构体不随 TCP 连接建立/关闭而 malloc/free,而是通过空闲链表 free_connections 统一调度:
- 新客户端连接到来(accept),从链表头取一个结构体,绑定 socket fd 和事件回调
- 连接关闭后,重置字段(如 read/write handler、data 指针等),放回链表尾部供下次复用
- 该池只管“连接元数据”的生命周期,不管理 socket 本身;socket 关闭由内核或 upstream 模块决定
- 内存始终驻留,直到 Worker 进程退出,避免频繁堆分配开销
Upstream 后端连接池:每 server 独立 LRU 缓存
当 Worker 执行反向代理时,它会为每个 upstream server(如 10.0.1.5:8080)维护一个独立的空闲 socket 缓存队列,由 keepalive N 控制上限:
- 请求完成后,若响应含 Connection: keep-alive、连接无错误、未超时(默认 60 秒),则 socket 被标记 idle 并插入该 server 的队首
- 下一次发往同一 server 的请求,优先从队列取空闲 socket,跳过三次握手和 TLS 握手
- 超时由全局定时器统一扫描清理,不是按连接单独设 timer
- 不同 server 之间绝不共享连接,哪怕 IP 相同但端口不同也视为独立池
复用生效的关键协同点
Worker 要真正复用后端连接,必须同时满足三个条件,缺一不可:
-
协议层面:设置
proxy_http_version 1.1,确保与后端协商 keep-alive -
头部净化:用
proxy_set_header Connection ""清除客户端传来的 Connection 头,防止透传 close 导致误断 -
池容量可用:当前 server 的空闲连接数未达
keepalive N上限,且有活跃连接可回收
资源隔离与生命周期边界
Worker 中的两类“池”严格区分用途和释放时机:
- c->pool(连接内存池):随 ngx_connection_t 创建而生,连接关闭即销毁,适合放 SSL 上下文、长连接 buffer
-
r->pool(请求内存池):每个 HTTP 请求独享,请求结束(
ngx_http_free_request)整池释放 - upstream 复用逻辑中所有临时变量、回调上下文必须分配在对应池中;若把 r->pool 分配的指针存到 c->data,下次复用该连接时会访问已释放内存











