Home » Ошибки » Nginx - Too many open files

Nginx - Too many open files

Небольшая заметка по одной из ошибок nginx, с которой вы можете столкнуться по мере роста нагрузки на web сервер. Исправляется она легко, но я оставлю небольшие комментарии по ней, чтобы было понимание причины.

Если у вас есть желание научиться работать с роутерами микротик и стать специалистом в этой области, рекомендую по программе, основанной на информации из официального курса MikroTik Certified Network Associate. Курс стоящий, все подробности читайте по ссылке. Есть бесплатные курсы.

Полностью эта ошибка будет выглядеть примерно так:

[alert] 24315#24315: *380953159 socket() failed (24: Too many open files) while connecting to upstream

К этой ошибке приводит системное ограничение на количество открытых файлов для рабочего процесса. Посмотреть это ограничение можно простой командой в консоли.

# ulimit -n
1024

Она равна 1024. Можно изменить системные лимиты, но есть более простое и разумное решение. Нет смысла менять системный лимит, если нас интересуют только процессы nginx. Для изменения лимита только для них, если отдельный параметр в конфигурации nginx - worker_rlimit_nofile (ссылка на официальную документацию).

Остается один вопрос - какое значение туда поставить. Я нашел информацию, что на каждое соединение nginx открываются два файловых дескриптора - один на соединение, один непосредственно на открытие файла. Я не смог найти подтверждения, но даже если эта информация не верна, ничего страшного не будет, если мы каждому соединению оставим 2 файловых дескриптора.

Теперь рассчитаем, какое значение в параметре worker_rlimit_nofile нам надо установить. Допустим, у нас есть 4-х ядерный сервер с такими параметрами nginx:

worker_processes  auto;
events {
    worker_connections  5120;
}

В данном случае у нас количество запущенных процессов будет автоматически равно количеству ядер. А на один процесс разрешено 5120 соединений. Таким образом, суммарно у нас может быть 5120 * 4 = 20480 соединений. На каждое соединение нужно 2 файловых дескриптора. Значит параметр worker_rlimit_nofile должен быть равен 40960:

worker_rlimit_nofile 40960;

После изменения достаточно просто перечитать конфигурацию.

# nginx -s reload

Проверить, применились ли новые лимиты на процессы nginx можно, выполнив следующую команду в консоли:

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 - Too many open files

Все в порядке, системный лимит остался дефолтным, а для процессов nginx изменился. Более подробно о том, как настроить nginx читайте в отдельной большой статье с примерами.

Онлайн курс Основы сетевых технологий

Теоретический курс с самыми базовыми знаниями по сетям. Курс подходит и начинающим, и людям с опытом. Практикующим системным администраторам курс поможет упорядочить знания и восполнить пробелы. А те, кто только входит в профессию, получат на курсе базовые знания и навыки, без воды и избыточной теории. После обучения вы сможете ответить на вопросы:
  • На каком уровне модели OSI могут работать коммутаторы;
  • Как лучше организовать работу сети организации с множеством отделов;
  • Для чего и как использовать технологию VLAN;
  • Для чего сервера стоит выносить в DMZ;
  • Как организовать объединение филиалов и удаленный доступ сотрудников по vpn;
  • и многое другое.
Уже знаете ответы на вопросы выше? Или сомневаетесь? Попробуйте пройти тест по основам сетевых технологий. Всего 53 вопроса, в один цикл теста входит 10 вопросов в случайном порядке. Поэтому тест можно проходить несколько раз без потери интереса. Бесплатно и без регистрации. Все подробности на странице .
Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Zerox
Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

7 комментариев

  1. Аватар

    Данный вариант уже не актуален и не меняется.
    Данное значение теперь меняется через systemctl
    # vi /etc/sysctl.conf
    fs.file-max = 64000

    Edit /etc/security/limits.conf and add:
    nginx soft nofile 64000
    nginx hard nofile 64000

    echo 'NGINX_ULIMIT="-n 64000"' >> /etc/sysconfig/nginx

    Edit /usr/lib/systemd/system/nginx.service and add a line in the [Service] section:
    LimitNOFILE=64000

    In /etc/sysconfig/nginx.systemd add:
    LimitNOFILE=64000

    Reload system daemon:
    # systemctl --system daemon-reload
    # sysctl -p

    Restart nginx:

    # /etc/init.d/nginx restart

    • Zerox

      Почему не актуален? Через systemctl или системные лимиты напрямую и раньше можно было поменять. Это не принципиально. Вы проверяли предложеннный мной вариант и он не сработал?

      • Аватар

        Верно. Я проверил.
        И я сталкиваюсь с данной проблемой очень часто.

        Попробуйте на centos или ubuntu ваш вариант и проверьте реальный кейс :)

      • Аватар

        Вы похоже не не помните, когда из за нового патча ядра, ограничения sysctl, ломали mysql открытие множества файлов, из за чего mysql работал так же не корректно.

    • Аватар

      Сейчас не service управляет процессом, а systemd.
      Из за чего ваш вариант подходит только для старых систем, где основной процесс запуска был через init.d

      • Аватар
        Владимир

        И сейчас всё работает.
        nginx -s reload
        может только не отрабатывать из-за того что в официальном репо в nginx.conf есть строка
        pid /run/nginx.pid;

        А в файле /usr/lib/systemd/system/nginx.service
        PIDFile=/var/run/nginx.pid

        Из-за этого nginx -s reload естественно выдаёт
        nginx: [error] invalid PID number "" in "/run/nginx.pid"

        Нужно просто в nginx.conf строку заменить на
        pid /var/run/nginx.pid;

        И всё заработает и лимиты по nginx -s reload применяются (проверил на CentOS / RHEL 7)

    • Аватар

      Работает, спасибо! А пример в статье у меня не заработал.

Добавить комментарий

Ваш адрес email не будет опубликован.

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.