Nginx通过单线程+异步非阻塞I/O+连接池复用管理keepalive长连接,依赖epoll/kqueue高效事件通知,由keepalive_timeout、keepalive_requests等指令精细控制连接生命周期,并通过内存池降低开销,需协同调优worker_connections与系统限制。

nginx 的事件模型与 keepalive 长连接的并发管理是紧密耦合的,核心在于:它不靠多线程或多进程维持连接,而是依托单线程(worker)+ 异步非阻塞 I/O + 连接池复用,实现高并发长连接管理。关键不在“保持连接”,而在“高效复用连接状态”和“及时回收空闲连接”。
epoll(Linux)或 kqueue(BSD)是底层支撑
nginx 在支持的系统上默认启用高效的内核事件通知机制:
- Linux 下使用 epoll,可 O(1) 时间复杂度监听成千上万 socket 状态变化,避免 select/poll 的遍历开销;
- 每个 worker 进程绑定一个 epoll 实例,独立处理所属连接,无锁竞争;
- 当 keepalive 连接空闲时,socket 被挂起在 epoll_wait 中,不消耗 CPU;一旦有新请求到达或超时触发,立即唤醒处理。
keepalive 相关指令控制连接生命周期
nginx 不自动无限维持长连接,而是通过显式配置精细调控:
-
keepalive_timeout:定义客户端空闲后服务器保持连接打开的最长时间(如
keepalive_timeout 65s;),超时后主动发送 FIN 关闭连接; -
keepalive_requests:限制单个连接最多处理多少个请求(如
keepalive_requests 100;),防止单连接长期占用资源或积累状态; - send_timeout / client_header_timeout:分别控制响应发送、请求头读取阶段的等待上限,防止慢客户端拖垮连接槽位。
连接池与内存复用降低开销
nginx 在 worker 内部维护连接池(ngx_connection_t 结构体池),配合 slab 分配器管理内存:
- 每次 accept 新连接或复用 keepalive 连接,都从池中快速分配/重置结构体,避免频繁 malloc/free;
- HTTP 请求处理完成后,若满足 keepalive 条件(如 HTTP/1.1、Connection: keep-alive、未达请求数上限),连接不关闭,仅重置读写缓冲区与请求上下文,等待下一次 read 事件;
- 整个过程无线程切换、无连接重建握手(TCP 三次握手、TLS 握手若启用 session resumption 也可跳过),显著降低延迟与系统调用开销。
worker_connections 与系统限制需协同调优
单个 worker 能管理的 keepalive 连接数受多重约束,需整体评估:
-
worker_connections 是 nginx 层面软上限(如
worker_connections 10240;),代表该 worker 可注册到 epoll/kqueue 的最大文件描述符数; - 实际可用连接数还受限于:系统级 ulimit -n(必须 ≥ worker_connections × worker_processes)、可用内存(每个连接约占用几 KB 内存)、TIME_WAIT 连接堆积(对反向代理场景更关键);
- keepalive 连接本身不占新端口,但会持续占用 fd 和内存,因此 过长的 keepalive_timeout 或过大的 worker_connections 设置,反而可能导致 fd 耗尽或内存压力上升。

















