У вас мощный сервер с десятком простых сайтов, клиенты довольны, сайты быстро открываются и регулярно обновляются. Приток посетителей с каждый днем все больше и больше. Но в один прекрасный момент эта идилия закончится, клиенты начнут жаловаться на частое появление ошибки 500. А почему она возникает? Давайте разберемся с одним из случаев.
Любая конфигурация связки apache+nginx с настройками по умолчанию когда-нибудь приведет к регулярному появлению ошибки 500. Почитав логи nginx вы увидите следующее:
2015/02/15 12:55:34 [alert] 20231#0: accept() failed (24: Too many open files) while accepting new connection on 0.0.0.0:8082 2015/02/15 12:55:34 [alert] 20231#0: accept() failed (24: Too many open files) while accepting new connection on 0.0.0.0:8082 2015/02/15 12:55:34 [alert] 20231#0: accept() failed (24: Too many open files) while accepting new connection on 0.0.0.0:8082 2015/02/15 12:55:34 [alert] 20231#0: accept() failed (24: Too many open files) while accepting new connection on 0.0.0.0:8082 2015/02/15 12:55:34 [alert] 20231#0: accept() failed (24: Too many open files) while accepting new connection on 0.0.0.0:8082
При достаточно большом количестве посетителей файл nginx error.log может вырасти с 1мб до десятков гигабайт.
Ошибка связана с ограничением на одновременные подключения к серверу и соответствнно на одновременно открытые файлы. По умолчанию один процесс может открыть 1024 файла.
Для начала давайте посмотрим ограничения в системе, а далее поднимем лимит на открытые файлы.
Посмотреть текущее ограничение из консоли:
//смотрим от пользователя root ulimit -n //от пользователя www-data (это по умолчанию, у вас может быть другой пользователь) su - www-data ulimit -Hn ulimit -Sn
В стандартной настройке системы оба значения будут равны 1024
Чтобы посмотреть системные ограничения в красивом виде выполните в консоли следующую команду:
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 1024 files Currently open files: 967
nginx: master process /usr/sbin/nginx Limit Soft Limit Hard Limit Units Max open files 1024 1024 files Currently open files: 783
Вот мы и убедились, что процесс nginx на грани по лимиту открытых файлов. На одно соединение выделяется по два файловых дескриптора, один для соединения с клиентом, а другой для открытия файла на диске. Добавляем worker_rlimit_nofile в самое начало конфигурационного файла /etc/nginx/nginx.conf
# Количество файловых дескрипторов которые будет использовать Nginx worker_rlimit_nofile 16384; # Меняем максимальное количество процессов (один процесс на одно ядро процессора) worker_process 4; # Количество соединений на процесс worker_connections 4096;
Принцип установки зачений очень простой: worker_process * worker_connections = worker_rlimit_nofile
Таким образом мы увеличили лимит открытых файловых дескрипторов и ускорили работу nginx за счет дополнительных процессов. Но, а как же система отнесется к таким запросам nginx? Ведь лимит открытых файлов для процессов как был 1024 так и остался неизменным. Сейчас мы это исправим.
Выполняем в консоли команду:
ulimit -n 16384
в /etc/security/limits.conf добавляем строки:
* soft nofile 16384 * hard nofile 16384
Теперь проверяем конфиг:
nginx -t
и перечитываем конфиги:
service nginx reload
На этом все! Nginx готов к росту посещаемости ваших проектов, стабильной и безотказной работе.
Оригинал статьи: http://useful-notes.ru/109-repair-nginx-accept-failed-24-too-many-open-files