nginx连接池分worker级和upstream级:前者为worker进程内固定大小的ngx_connection_t结构体池,按需复用元数据;后者为每个upstream server维护的lru空闲socket缓存队列,受keepalive指令限制,超时由定时器统一清理。

Nginx 连接池的生命周期不是靠“长期驻留”维持的,而是严格绑定在具体上下文里,按需创建、自动释放。理解这点,才能避免连接泄漏、内存悬空或复用失败。
worker 级连接池:固定容量,复用结构体
每个 worker 进程启动时,会预分配一个大小为 worker_connections 的 ngx_connection_t 数组——这叫“连接池”,但它不等于活跃 TCP 连接,只是连接描述符的容器池。
- 数组本身生命周期与 worker 进程一致,不销毁;
- 其中每个 ngx_connection_t 结构通过 free_connections 链表统一管理;
- accept 新连接时,从链表取一个空闲结构;连接关闭后,重置状态并放回链表;
- 它不管理 socket 生命周期,只管理连接元数据结构的复用。
upstream 连接池:按 server 粒度缓存空闲 socket
这是真正复用后端 TCP 连接的地方,由 ngx_http_upstream_keepalive_module 实现,本质是 LRU 缓存队列,不是常驻连接集合。
- 每个 upstream server(如
backend:8080)独享一个空闲连接队列; - 最大缓存数由 keepalive N 指令控制,仅限制“已用完、未关闭”的空闲连接数;
- 连接归还时插入队首,超时由全局定时器统一触发(默认 60 秒,不可配);
- 它不主动建连、不做健康检查,完全依赖 proxy 模块判断是否可复用(比如响应体收完、连接未出错、协议支持 keep-alive)。
内存池与连接/请求的强绑定关系
连接和请求各自拥有专属内存池,决定了其上挂载资源的生存边界:
- c->pool(连接池):随 ngx_connection_t 创建而生,连接关闭时销毁,适合存 SSL 上下文、长连接缓冲区等;
-
r->pool(请求池):每个 HTTP 请求独有,请求结束(
ngx_http_free_request)即整池释放; - 所有 upstream 复用逻辑中涉及的临时结构、回调上下文、buffer 分配,都必须落在对应池中;
- 若把 r->pool 中分配的指针保存到 c->data 或全局变量,下次请求复用该连接时,该指针已失效。
事件驱动下的协同清理机制
连接池行为由 epoll/kqueue 事件循环驱动,而非独立线程轮询:
- 空闲 upstream 连接归还后,读写事件监听被关闭,仅保留 socket 句柄;
- 超时清理由
ngx_event_expire_timers()统一触发,扫描所有待过期连接; - client 端 keepalive_timeout 和 upstream keepalive 超时互不影响:前者管前端连接复用,后者管后端连接复用;
- 一旦请求 finalize,整个 r->pool 销毁,所有关联的 upstream 复用状态、临时 buffer、ctx 数据全部清空。











