“too many open files”是系统文件描述符四层限制未对齐所致,须同步调优内核fs.file-max、用户limits.conf、systemd limitnofile及nginx.conf中worker_rlimit_nofile与worker_connections,缺一不可。

默认1024个文件描述符,根本撑不住高并发场景。Nginx每建立一个连接、打开一个日志文件、读取一个静态资源,都会消耗至少1个句柄。当并发连接数接近或超过这个限制时,你会看到 “Too many open files” 错误,新连接被直接拒绝,error.log里频繁出现 “accept() failed (24: Too many open files)” ——这不是配置写错了,是系统拦住了你。
确认当前限制并分层突破
文件描述符限制存在于三个层级:系统级、用户级、进程级。必须逐层检查并同步提升,否则只调其中一层等于白做。
-
系统全局限制:查看
/proc/sys/fs/file-max,建议设为2097152(200万),执行:echo 2097152 > /proc/sys/fs/file-max,并写入/etc/sysctl.conf持久化 -
用户级限制(nginx运行用户):编辑
/etc/security/limits.conf,追加两行:nginx soft nofile 1048576nginx hard nofile 1048576
注意:若用 systemd 启动,还需在/etc/systemd/system/nginx.service.d/override.conf中添加LimitNOFILE=1048576,否则 limits.conf 不生效 -
Nginx 进程级限制:在 nginx.conf 的 main 块中设置:
worker_rlimit_nofile 1048576;
它必须 ≥ 单个 worker 的最大连接数(即worker_connections)
worker_connections 与实际并发能力的换算逻辑
很多人以为把 worker_connections 1048576 就能支持百万连接,其实漏了关键前提:worker 数量和系统资源是否匹配。
- 最大理论并发连接数 =
worker_processes × worker_connections - 但真实可用值受内存制约:每条空闲 keep-alive 连接约占用 12–20 KB 内存(含 socket buffer、connection struct、SSL session 等)。100 万连接 ≈ 12–20 GB 内存仅用于连接状态管理
- 推荐配置节奏:
4 核机器 →worker_processes auto;(自动匹配 CPU 核心数)
每 worker 分配worker_connections 262144;(256K),总连接能力超百万,留出余量应对突发新建连接
压测中验证句柄是否真正就位
光改完配置不验证,等于没调。真实压测时要交叉比对三组数据:
- 用
lsof -u nginx | wc -l实时统计 nginx 用户打开的句柄总数,对比预期峰值 - 在压测中观察
ss -s输出的total:行,看used是否逼近file-max - 检查 Nginx 自身指标:
curl http://localhost/stub_status(需启用 ngx_http_stub_status_module),关注Active connections和Accepts/Handled/Requests比值 —— 若Handled ,说明有连接被丢弃,大概率是句柄不足或 accept 队列溢出
配套必须调整的内核参数
句柄数量上去了,但内核网络栈跟不上,照样卡在连接建立环节。以下三项必须同步优化:
-
net.core.somaxconn = 65535:提升 listen socket 的等待队列长度,避免 SYN 请求被丢弃 -
net.ipv4.tcp_max_syn_backlog = 65535:配合 somaxconn,防止高并发建连时 SYN 队列溢出 -
net.core.netdev_max_backlog = 5000:网卡收包队列,防止突发流量下数据包被内核丢弃
这些参数同样需写入 /etc/sysctl.conf 并执行 sysctl -p 加载。











