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

Nginx — Too many open files

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

Если у вас есть желание научиться строить и поддерживать высокодоступные и надежные системы, рекомендую познакомиться с онлайн-курсом «DevOps практики и инструменты» в OTUS. Курс не для новичков, для поступления нужно пройти .

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

[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 читайте в отдельной большой статье с примерами.

Онлайн курс "DevOps практики и инструменты"

Если у вас есть желание научиться строить и поддерживать высокодоступные и надежные системы, научиться непрерывной поставке ПО, мониторингу и логированию web приложений, рекомендую познакомиться с онлайн-курсом «DevOps практики и инструменты» в OTUS. Курс не для новичков, для поступления нужны базовые знания по сетям и установке Linux на виртуалку. Обучение длится 5 месяцев, после чего успешные выпускники курса смогут пройти собеседования у партнеров. Проверьте себя на вступительном тесте и смотрите программу детальнее по .
Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

Помогла статья? Есть возможность отблагодарить автора

Автор Zerox

Zerox
Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству.

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

  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

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

Ваш e-mail не будет опубликован.

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