Nginx: Too many open files

Как исправить ошибку nginx (24: Too many open files)

Применимо к Debian 8 (systemd).

Сайт стал периодически выдавать 500-ю ошибку, а в логах nginx появляться запись: "...socket() failed (24: Too many open files) while connecting to upstream...".

Скорее всего, исчерпан лимит на максимальное количество открытых файлов. Ограничения делятся на Soft Limit и Hard Limit. Смысл разделения в том, что менять жесткие может только привелигированный процесс. По умолчанию на процесс выдается возможность открыть 1024 файла.

Для начала посмотрим, какое же в принципе количество файлов можно открыть:

cat /proc/sys/fs/file-max
346966

Посмотреть текущие ограничения можно, выполнив команду:

for pid in `pidof nginx`; do echo "$(< /proc/$pid/cmdline)"; egrep 'files|Limit' /proc/$pid/limits; echo "Currently open files: $(ls -1 /proc/$pid/fd | wc -l)"; echo; done

Результат:

nginx: worker process
Limit                     Soft Limit           Hard Limit           Units
Max open files            1024                 2048              files
Currently open files: 1022

nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
Limit                     Soft Limit           Hard Limit           Units
Max open files            1024                 2048              files
Currently open files: 743

ОК. Не изобретая велосипед зададим для nginx предел на 16384.

1) Для начала надо изменить системные ограничения. В /etc/security/limits.conf добавить строки:

* soft nofile 16384
* hard nofile 16384

И от рута выполнить:

ulimit -n 16384

2) Далее меняем ограничения в конфигурации nginx. В nginx.conf прописать новое значение worker_connections, равное 16384, деленное на количество worker_processes. Установить для worker_rlimit_nofile значение 16384

3) Таким образом мы изменили ограничения для worker process, но не для master process

Создать директорию

/etc/systemd/system/nginx.service.d

В ней создать файл worker_files_limit.conf и поместить в него:

[Service] 
LimitNOFILE=16384

Затем перезапустить systemd и nginx:

systemctl daemon-reload
systemctl restart nginx.service