UMGUM.COM 

Nginx + file limits ( Устраняем проблему с эпизодическими сбоями соединений с "FastCGI" и разбираемся с ограничениями файловой системы "Linux". )

1 октября 2017  (обновлено 11 июня 2019)

OS: "Linux Debian 7/8/9", "Linux Ubuntu 14/16/18 LTS".
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

Применяем его немедленно:

# 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;
  ....
}
....

# 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


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )