Applications: "Nginx".
Задача: устранить проблему с эпизодическими сбоями соединений с "FastCGI" и разобраться с ограничениями файловой системы "Linux", препятствующими работе "Nginx" в условиях высокой нагрузки с большим количеством конкурентных клиентских подключений.
Корректируем лимит соединений с файловыми сокетам.
Симптом: ошибка "502 Gateway" в браузере и отметка в журнале событий:
... connect() to unix:/var/run/php/php-fpm.sock failed (11: Resource temporarily unavailable) while connecting to upstream...
Суть проблемы в том, что "Nginx" пытается открыть соединение с локальным файловым сокетом тогда, когда общее количество уже инициированных подобралось к скромному общесистемному лимиту (default: 128):
# sysctl net.core.somaxconn
Создаём выделенный, автоматически подключаемый при загрузке операционной системы, файл конфигурации:
# vi /etc/sysctl.d/30-sl-nginx.conf
# Увеличиваем ограничение на количество открытых соединений к файловым сокетам (default: 128)
net.core.somaxconn=4096
# Увеличиваем ограничение на количество ожидающих запросов открытия соединений к файловым сокетам (default: 1000)
net.core.netdev_max_backlog=2048
net.core.somaxconn=4096
# Увеличиваем ограничение на количество ожидающих запросов открытия соединений к файловым сокетам (default: 1000)
net.core.netdev_max_backlog=2048
Применяем его немедленно:
# sysctl -p -f /etc/sysctl.d/30-sl-nginx.conf
Корректируем лимит количества открытых файлов.
Симптом: ошибка "502 Gateway" в браузере и отметка в журнале событий:
... socket() failed (24: Too many open files) while connecting to upstream..., upstream: "fastcgi://unix:/var/run/php/php-fpm.sock:" ...
Суть проблемы в том, что изначально "Nginx" работает в контексте довольно скромных системных ограничений, если таковые не переопределены явно в его конфигурации. На каждое обрабатываемое соединение "Nginx" инициирует по два файловых дескриптора (иначе говоря, открывает два файла), причём это делается как для обработки запросов посредством "FastCGI", проксировании и даже выдаче статичных файлов. По умолчанию "Nginx" в один момент может открыть то количество файлов, которое ограничено подсистемой "Linux User Limits" глобально или точечно конкретному пользователю (default: 1024):
# ulimit -n
В попытках обслужить большое количество пользовательских запросов "Nginx" легко подбирается к границе установленного лимита и упирается в неё. Это легко исправляется параметрами его же конфигурации, которые переопределяют общесистемные установки:
# vi /etc/nginx/nginx.conf
....
# Задаём число рабочих процессов (для начала отталкиваемся от количества ядер CPU; default: 1)
worker_processes 24;
# Указываем максимальное число открытых файлов (RLIMIT_NOFILE) для рабочих процессов (default: "ulimit -n" ~ 1024)
# (на каждое обрабатываемое соединение выделяется по два файловых дескриптора)
# (worker_rlimit_nofile = worker_processes * worker_connections * 2)
worker_rlimit_nofile 50000;
events {
# Задаём максимальное число соединений, которые одновременно может открыть рабочий процесс (default: 512)
worker_connections 1024;
....
}
....
# Задаём число рабочих процессов (для начала отталкиваемся от количества ядер CPU; default: 1)
worker_processes 24;
# Указываем максимальное число открытых файлов (RLIMIT_NOFILE) для рабочих процессов (default: "ulimit -n" ~ 1024)
# (на каждое обрабатываемое соединение выделяется по два файловых дескриптора)
# (worker_rlimit_nofile = worker_processes * worker_connections * 2)
worker_rlimit_nofile 50000;
events {
# Задаём максимальное число соединений, которые одновременно может открыть рабочий процесс (default: 512)
worker_connections 1024;
....
}
....
# nginx -t && nginx -s reload
После применения изменений можно полюбоваться новыми значениями ограничений в красивой таблице с разбивкой сведений по каждому процессу:
# 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