worker_connections是每个worker进程通过epoll管理的就绪态文件描述符总数,包含客户端socket、上游连接等,需与ulimit -n、worker_rlimit_nofile及epoll事件模型协同调优,否则无效。

worker_connections 不是“并发连接数上限”的简单计数器,而是 Nginx 每个 worker 进程能通过 epoll 管理的就绪态文件描述符(fd)总数。它直接对应 epoll 实例中可注册、可监听的 fd 容量,包括客户端 socket、上游连接、缓存文件句柄等——不是只算“活跃请求”,而是所有已建立且需事件监控的资源。
每个 worker 独占一个 epoll 实例,worker_connections 就是它的容量上限
Nginx 启动后,每个 worker 进程调用 epoll_create() 创建专属 epoll 实例(epfd),再用 epoll_ctl() 把监听 socket 和后续 accept 到的所有 client socket 注册进去。worker_connections 的值,就是这个 epfd 能容纳的最大 fd 数量。一旦超过,新连接会被拒绝或丢弃,系统日志会出现 “too many open files” 或 “accept() failed (24: Too many open files)”。
- 多个 worker 之间不共享 epoll 实例,不存在锁竞争或事件争抢
- worker_connections 设为 10240,并不意味只能服务 10240 个用户;如果大量连接处于 keepalive 空闲状态,实际承载的总连接数可能远超该值,只要就绪事件不超限
- 真正制约的是“同时有数据可读/可写”的连接数,而非 TCP 连接总数
epoll 的 ET 模式 + 非阻塞 I/O 让 worker_connections 发挥真实吞吐
worker_connections 的效能高度依赖 epoll 的边缘触发(ET)模式与非阻塞 socket 的配合。Nginx 默认启用 ET,并强制所有 socket 设置为 non-blocking。这意味着:
- 一个 socket 有数据到达时,epoll_wait 只通知一次;Nginx 必须循环调用 recv()/send() 直到返回 EAGAIN,才算处理完本次就绪事件
- 这种“一次唤醒、批量处理”机制,避免了重复事件通知开销,也让单个 worker 能在一次事件循环中高效消化多个就绪 fd
- 若未设为非阻塞,recv() 可能卡住,导致整个 worker 停摆,worker_connections 再大也形同虚设
空闲连接几乎不消耗 worker_connections 的有效配额
HTTP keepalive 或 WebSocket 长连接大部分时间处于空闲状态,它们只是挂在 epoll 的红黑树里,不触发回调、不占用栈空间、不分配额外内存。只有当客户端发来新请求(EPOLLIN 就绪)或响应需要发送(EPOLLOUT 就绪)时,才会被 epoll_wait 返回,进入 Nginx 事件处理流程。
- keepalive_timeout 控制空闲连接生命周期,超时后自动关闭,防止 fd 泄漏
- 所以 worker_connections 的真实压力,取决于单位时间内“就绪事件发生频次”,而非连接总数
- 百万级连接场景下,只要就绪事件分布均匀、处理及时,worker_connections 即使设为 65536 也能稳定承载
必须与系统级限制协同,否则 worker_connections 形同虚设
worker_connections 再高,若系统 ulimit -n 或 fs.file-max 不够,Nginx 启动时会降级或报错。常见错误如:"8192 worker_connections are more than open file resource limit: 1024"。
- 先执行 ulimit -n 查看当前 shell 限制,再用 sysctl fs.file-max 查全局上限
- 修改 /etc/security/limits.conf(如 * soft nofile 65536)、/etc/sysctl.conf(fs.file-max = 2097152),并生效
- 在 nginx.conf 中显式配置 worker_rlimit_nofile 65536,确保 worker 进程能突破默认限制
- use epoll; 建议显式声明,尤其跨平台部署或容器环境,避免因编译选项导致回退到低效 poll 模型











