Nginx Worker进程不管理连接生命,而是通过预分配连接槽、状态机驱动、事件触发与定时器统一清理实现高效复用;连接结构体可循环使用,请求池与连接池内存生命周期严格分离,超时与关闭均由事件循环统一处理。

Nginx 的 Worker Process 并不“管理连接生命”本身,而是通过一套轻量、确定、事件驱动的复用机制,让连接在生命周期内被高效承载和释放。它不维护连接状态,也不主动保活或探测,一切围绕“结构复用 + 状态归零 + 事件触发”展开。
Worker 进程内连接结构是预分配、可复用的槽位
每个 Worker 启动时就一次性分配好 worker_connections 个 ngx_connection_t 结构体,组成固定大小的连接池。这些结构体不是每次新连接都 malloc 出来,也不是每个连接独占一个——它们是可循环使用的“连接槽”。
- 新连接到来(accept),从空闲链表取一个槽,绑定 socket 和事件;
- 连接关闭后,不销毁结构体,只是重置字段(如
c->read->handler、c->data)、清空关联的请求池,再放回空闲链表; - 只有 Worker 进程退出时,整个数组才真正释放。
连接生命周期由状态机与事件协同驱动
连接在 Worker 内并非简单“打开→使用→关闭”,而是在以下状态间流转:
-
idle:刚 accept,等待读事件; -
active:正在处理请求(r->pool 已创建); -
reusable:请求结束、响应发完、keepalive 开启 → 连接未关闭,但请求池已销毁,ngx_connection_t暂挂起,等待下一次 read ready; -
closed:超时、错误或显式 close,最终调用ngx_free_connection归还槽位。
请求与连接的内存生命周期严格分离
-
c->pool(连接池):随ngx_connection_t创建而生,连接关闭(非 keepalive 场景)或 Worker 退出时销毁,适合存 SSL 上下文、长连接缓冲区等跨请求资源; -
r->pool(请求池):每个 HTTP 请求独有,ngx_http_finalize_request触发后整池释放,所有模块临时分配的内存(headers、body buffer、ctx)一并回收; - ⚠️ 关键约束:不能把
r->pool中分配的指针保存到c->data或全局变量里——下次复用该连接时,那些内存早已无效。
空闲连接不靠轮询,靠定时器统一清理
- keepalive 超时(
keepalive_timeout)由全局定时器ngx_event_expire_timers()扫描触发,不是每个连接单独起 timer; - upstream 空闲连接超时(
keepalive N)同样由统一定时器管理,默认 60 秒,不可配置; - 客户端 keepalive 和 upstream keepalive 互不影响:前者控制前端复用,后者控制后端 socket 复用。
真正的“连接管理”其实是资源边界控制
Worker 进程不干预业务逻辑,只确保:
- 每个连接最多处理
keepalive_requests次请求,防止单连接无限复用导致内存累积; - 每个连接空闲时间不超过
keepalive_timeout,避免空闲句柄长期占用 fd; - 所有 socket 操作(read/write/close)都在 epoll/kqueue 事件循环中完成,无阻塞、无线程竞争;
- 异常中断(如 client 断连、read timeout)最终都会走到
ngx_close_connection,完成 socket 关闭、事件注销、timer 清理、槽位归还全流程。
不复杂但容易忽略。


















