需协同调优Nginx进程级与内核级文件描述符限制:先设systemd的LimitNOFILE≤fs.file-max并留10%余量,再使worker_rlimit_nofile≥worker_connections×1.2~1.5,最后通过ss、/proc/sys/fs/file-nr和stub_status持续验证监控。

要解决海量并发连接下因系统句柄不足导致的 worker_rlimit_nofile 相关溢出问题,核心在于协同调优 Nginx 进程级限制与内核级资源上限,而非单独修改某一项配置。
理解 worker_rlimit_nofile 的作用边界
该指令设置的是 Nginx 工作进程能打开的最大文件描述符数量(即 socket、日志文件、临时文件等总和),但它不能突破操作系统对单个进程的 RLIMIT_NOFILE 限制,更无法绕过全局的 fs.file-max。若未同步调整系统层限制,Nginx 启动时会静默截断为系统允许值,或在高并发时触发 accept() failed (24: Too many open files) 错误。
- 可通过
ulimit -n查看当前 shell 启动 Nginx 时的默认 soft limit - 用
cat /proc/$(pgrep nginx)/limits | grep "Max open files"确认实际生效值 - 若输出中
Max open files的 soft 值低于worker_rlimit_nofile配置,说明被系统限制覆盖
同步调整 systemd 服务单元的资源限制
现代 Linux 发行版(如 CentOS 7+/Ubuntu 16.04+)多通过 systemd 托管 Nginx,其默认继承系统默认 limits,需显式覆盖:
- 编辑
/etc/systemd/system/nginx.service.d/override.conf(若不存在则新建) - 添加如下内容:
[Service] LimitNOFILE=1048576 LimitNPROC=65536
- 执行
systemctl daemon-reload && systemctl restart nginx生效 - 注意:此处数值需 ≤
/proc/sys/fs/file-max,且建议留 10% 余量供其他进程使用
合理设置 worker_rlimit_nofile 与 worker_connections
二者必须匹配:每个工作进程最多处理 worker_connections 个连接,而每个连接至少占用 1 个 fd(客户端 socket),加上监听 socket、上游连接、日志文件等,实际消耗通常为 worker_connections × 1.2~1.5。
- 若
worker_connections 10240,建议worker_rlimit_nofile至少设为16384 - 若启用
http_v2或大量 upstream keepalive,fd 消耗更高,应按压测结果反推(例如实测峰值 fd 占用达 13000,则设为 16384 更稳妥) - 避免盲目设为百万级——单进程 fd 过高可能引发内核调度开销上升,反而降低吞吐
验证与持续监控不可省略
调优后必须验证是否真正生效,并建立长期观测机制:
- 用
ss -s查看当前 socket 总数,对比nginx -T | grep worker_connections推算理论容量 - 定期采集
/proc/sys/fs/file-nr(已分配/未使用/最大)三元组,识别是否存在持续接近file-max的趋势 - 在 Nginx 日志中开启
error_log ... debug_connection可捕获 fd 耗尽瞬间的上下文(仅调试期启用) - 推荐将
nginx_stub_status模块 + Prometheus + Grafana 组合,监控Active connections与系统nr_open比值

















