#Что означает ошибка
[alert] worker_connections exceed open file resource limit accept4() failed (24: Too many open files)
Каждое соединение и файл в Linux — дескриптор. У процесса есть лимит открытых дескрипторов (nofile), по умолчанию часто 1024. Nginx в рабочем режиме открывает по два дескриптора на соединение (клиент и бэкенд) плюс файлы и логи. При высоком worker_connections или нагрузке лимит исчерпывается, и в логе появляется Too many open files (24); клиенты получают обрывы или 502.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Низкий лимит nofile системыЛимит ОС или systemd мал. | cat /proc/PID/limits показывает 1024. | Увеличьте лимиты. |
| Слишком большое worker_connectionsЗначение больше лимита. | Предупреждение при старте. | Согласуйте с лимитом. |
| Утечка соединений в бэкендеБэкенд не закрывает соединения. | Число сокетов растёт. | Исправьте приложение. |
| Реальная нагрузкаМного клиентов и файлов. | Лимит исчерпывается при пиках. | Масштабируйте. |
#Пошаговое решение
- Проверьте текущий лимитЧерез SSH определите PID рабочего процесса Nginx:
pgrep -a nginx, затем посмотрите лимит именно этого процесса командойcat /proc/PID/limits | grep "open files"(PID замените фактическим числом). СообщениеToo many open filesотносится к лимиту дескрипторов, аworker_connections are not enough— к числу соединений: это не всегда одно и то же. - Посчитайте открытые дескрипторыДля найденного рабочего PID посчитайте записи в
/proc/PID/fd(sudo ls /proc/PID/fd | wc -l) и сопоставьте с количеством активных подключенийss -s. Повторите измерение под нагрузкой. Если дескрипторы близки к лимиту, найдите типы соединений, а не повышайте значения без расчёта памяти и нагрузки. - Увеличьте лимит nginxВ основном конфигурационном файле Nginx, вне блоков
http/events, параметрworker_rlimit_nofileможет поднять предел файловых дескрипторов для рабочих процессов; его значение нельзя выбирать только по примеру 65535. Сначала определите системный предел и действительныйLimitNOFILE, сделайте копию nginx.conf, затем подберите размер по ожидаемым соединениям и ресурсам. - Настройте worker_connectionsВ секции
eventsпараметрworker_connectionsограничивает количество соединений на рабочий процесс; при проксировании одно клиентское соединение может использовать дополнительное соединение к backend. Значение подбирайте с учётом числа worker-процессов, открытых файлов и доступной памяти. После изменения проверьте синтаксисsudo nginx -t. - Настройте systemdЕсли служба запущена systemd, узнайте настройки
systemctl show nginx -p LimitNOFILE. Для корректировки используйтеsudo systemctl edit nginxи секцию[Service]сLimitNOFILE=...по расчётному значению. Сохраните прежнюю конфигурацию и учитывайте, что применение черезsystemctl restart nginxпрерывает действующие соединения — назначьте окно обслуживания. - Настройте limits.confНе считайте
/etc/security/limits.confнадёжным способом для службы systemd: многие демоны получают лимиты от менеджера служб, а не пользовательского сеанса PAM. Изменяйтеlimits.confтолько если подтверждено, что конкретный процесс наследует его настройки; затем проверьте фактический/proc/PID/limits, а не только содержимое файла. - Проверьте конфигурациюПосле резервного копирования и
nginx -tпримените конфигурацию черезreload, если менялся лишь Nginx; изменение ограничений systemd обычно требуетdaemon-reloadи перезапуска конкретной службы в окно обслуживания. Снова определите PID, проверьте его лимиты и отсутствие ошибок в error.log. При ухудшении верните исходный файл и параметры службы. - Найдите причину ростаЕсли число соединений растёт постоянно, посмотрите состояния
ss -antи ошибки backend, ограничения upstream keepalive, количество медленных запросов. Большое количествоCLOSE_WAITможет относиться к приложению, но не доказывает утечку именно в Nginx. Поищите причину зависших соединений и сравните показатели до и после исправления. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
Значение worker_connections умножается на число воркеров; общий лимит дескрипторов должен быть не меньше worker_connections × 2. Для сильной нагрузки проверьте также net.core.somaxconn и net.ipv4.ip_local_port_range (sysctl). Если количество CLOSE_WAIT растёт, а не падает, устраните утечку в приложении или настройте proxy_read_timeout и keepalive. Документация — .