worker_connections 是单个 worker 进程事件循环可管理的就绪态文件描述符数量上限,涵盖监听 socket、客户端连接、上游连接等,决定 i/o 事件调度能力而非精确并发请求数。

worker_connections 不是并发连接数的硬上限,而是事件循环能同时管理的就绪态文件描述符(fd)数量上限。它直接约束单个 worker 进程内事件循环的“待办清单”容量。
worker_connections 是事件循环的资源配额
每个 worker 进程运行一个独立的事件循环,该循环依赖 epoll(Linux)等机制监听 fd 状态。worker_connections 设定的是这个循环内部可注册、跟踪和分发事件的最大 fd 数——包括监听 socket、客户端连接、上游连接、缓存文件句柄等。一旦达到该值,新 accept 的连接会被拒绝(除非配置了队列如 listen backlog),因为事件循环已无空间为其分配 ngx_event_t 结构体和关联上下文。
- 它不是“同时活跃请求”的精确计数,而是“可调度 I/O 实体”的总限额
- 一个 HTTP/1.1 Keep-Alive 连接在空闲时仍占用 1 个 fd,计入该限额
- 启用 proxy_http_version 1.1 + keepalive 后,每个 upstream 连接也消耗 1 个 fd
事件循环按需消费这个配额
事件循环本身不主动创建连接,而是响应内核通知后动态注册 handler。worker_connections 决定了它“能接住多少次通知”。例如:
- 监听 socket 就绪 → accept 新连接 → 消耗 1 个配额,为其注册读事件
- 客户端发来请求头 → 触发读 handler → 解析完可能注册 body 读事件(不新增 fd)或写事件(若响应立即发出,也复用原 fd)
- 向后端转发时建立 upstream 连接 → 新增 1 个 fd,计入配额
配额用满后,即使内核有新连接就绪,worker 也不会调用 accept,直到已有连接关闭、释放 fd。
配额与真实并发能力不等价
实际承载能力取决于事件循环如何利用这些 fd:
- 开启 sendfile:静态资源响应不经过用户态内存拷贝,减少 CPU 和临时 buffer 占用,让同一 fd 更快完成 I/O,提升吞吐
- 启用 reset_timedout_connection:及时清理卡死连接,避免 fd 被无效占用
- 配置 upstream keepalive:复用后端连接,避免每个请求新建 fd,大幅降低配额消耗速度
- 关闭 access_log 或异步写日志:防止日志 I/O 阻塞事件循环,间接保护 fd 配额用于核心路径
调优必须匹配事件循环行为
盲目调高 worker_connections 可能适得其反:
- 超过系统 ulimit -n 会导致 worker 启动失败或运行时 panic
- 远超物理内存支持的连接数,会触发频繁 swap,拖慢整个事件循环响应
- 若后端响应慢、连接长期挂起,高配额反而放大资源滞留,加剧超时堆积
合理值 = (预期峰值活跃 fd 数)× 安全余量(通常 1.2–1.5),并始终与 worker_processes、CPU 核心数、内存容量协同评估。











