Ubuntu 22.04 + nginx 1.18,压测到八百并发时 error.log 报 768 worker_connections are not enough,把 worker_connections 从 1024 提到 8192 还是同样的报错,ss 里 established 只有六百多条。

一开始怀疑是「systemd 的 LimitNOFILE 覆盖了 nginx.conf 里的设置,reload 不会重新套用这个限制」,查了一圈,方向不对。

把日志和配置对完,能解释这个现象的基本就这几处。worker_rlimit_nofile 没跟着改,进程的文件描述符卡在 1024,连接接进来也建不起来。少数情况下是反向代理每条连接要占两个描述符,前端的加上游的,实际消耗是并发数的一倍以上。

不容易想到的是,upstream 的 keepalive 池不设上限,空闲连接常驻,描述符被长期占着不还。

动手时先看 worker 进程真正拿到的描述符上限

cat /proc/$(pidof nginx | awk '{print $1}')/limits | grep 'open files'

随后确认 systemd 有没有覆盖这个值

systemctl show nginx -p LimitNOFILE

同时放开配置与 unit 两处上限

printf 'worker_rlimit_nofile 65535;\n' > /etc/nginx/conf.d/limits.conf && mkdir -p /etc/systemd/system/nginx.service.d && printf '[Service]\nLimitNOFILE=65535\n' > /etc/systemd/system/nginx.service.d/limits.conf && systemctl daemon-reload && systemctl restart nginx

等前面都确认过,再核对连接数与描述符分布

ss -s && ss -tan state established | wc -l

别只看报错消失,验证要多做一步。重启后 /proc 里 open files 的软限制显示 65535,压到两千并发 error.log 不再出现 worker_connections,ss -s 的统计与监控曲线一致。

reload 只换 worker 进程不换 unit 限制,改 LimitNOFILE 必须 restart,重启前先确认没有长连接业务。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189