Назад | Перейти на главную страницу

Nginx тысячи файлов конфигурации сервера очень медленно перезагружаются (nginx -s reload)

У меня есть один главный nginx.conf, куда я включаю остальные свои серверы (разделить блоки) с помощью директивы include:

include myservers/*.conf;

Моя проблема в том, что у меня есть новый файл конфигурации на моих серверах / мне нужно перезагрузить nginx с помощью nginx -s reload

Проблема требует много времени, чтобы перезагрузить сервер, занимает 1 минуту, и это будет расти, потому что у меня будет больше и восходящих серверов.

Видите ли вы какой-нибудь способ улучшить это?

Единственное решение, которое я нашел на данный момент, - это платная версия Nginx Nginx Plus API. https://docs.nginx.com/nginx/admin-guide/load-balancer/dynamic-configuration-api/ где вы можете динамически добавлять новые вышестоящие серверы с помощью REST API без перезагрузки.

Также я думал о том, чтобы иметь некую технику сегментирования с одним главным хеш-ключом wirth для подчиненных серверов (например, elasticsearch с алгоритмом RAFT для сохранения состояния консенсуса), поэтому, когда вам нужно обновить, вам нужно перезагрузить только один подчиненный сервер с меньшим количеством восходящих серверов.

Я запустил новую виртуальную машину (с хранилищем на SSD) и установил на нее nginx. А потом я написал сценарий для создания огромного количества файлов, каждый из которых содержит один server блок. Они выглядели примерно так:

[root@localhost ~]# cat /etc/nginx/sites/server047393.conf 
server {
    listen 80;
    listen [::]:80;
    server_name server047393;
}

Сначала я сделал 50 000 из них, но это заняло всего 9 секунд, чтобы перезагрузить nginx, поэтому я поднялся до 100 000. При этом на перезагрузку nginx постоянно уходило 20 секунд. Примерно первую половину этого времени занимает ожидание ввода-вывода диска, а во второй половине - ЦП. При таком количестве серверных блоков nginx использует почти 1 ГБ оперативной памяти.

Это действительно не похоже на проблему, если у вас нет конфигурации nginx на очень медленном диске. Он полностью перечитывается при перезагрузке или перезапуске nginx. С вращающимся диском перезагрузка может занять пару минут. Используйте SSD или даже RAM-диск для хранения конфигурации nginx.

Действительно, собственный nginx совет по оптимизации имен серверов почти не упоминает время разбора конфигурации. На самом деле это не то, о чем вы должны сильно заботиться. В нем много говорится о количестве времени, необходимом для определения правильного server блок для обработки входящего запроса. По умолчанию nginx пытается оптимизировать это, чтобы минимизировать пропуски строк кэша ЦП.

Чтобы оптимизировать это для большего количества имен серверов, вам может потребоваться ничего не делать, но вам, вероятно, потребуется настроить server_names_hash_max_size директива. Бегать nginx -t. Если вы видите такое сообщение:

nginx: [warn] could not build optimal server_names_hash, you should increase either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 64; ignoring server_names_hash_bucket_size

Тогда вам следует настроить server_names_hash_max_size. Начните с установки в два раза большего, чем количество server_nameвы создаете. Если у вас 30 000 имен серверов, начните с server_names_hash_max_size 32768.

В документе по оптимизации упоминается следующее:

если время запуска nginx недопустимо велико, попробуйте увеличить server_names_hash_bucket_size.

При тестировании я обнаружил, что это на самом деле не помогло, но если вы хотите попробовать, увеличивайте каждый раз в степени двойки. Это значение должно быть степенью двойки, иначе nginx не запустится. Это значение устанавливается по умолчанию в соответствии с размером строки кэша ЦП, поэтому, если вы находитесь на виртуальной машине и свойства ЦП не отображаются правильно для виртуальной машины, вы можете безопасно удвоить это число (или nginx отказался запускаться. во-первых, но это немного другое сообщение об ошибке, could not build the server_names_hash). Не переусердствуйте с этим, иначе ваши входящие запросы будут замедляться из-за промахов в кэше ЦП.

Сколько файлов и какая конфигурация у вас есть nginx -s reload занимает целую минуту ?!

Определите источник.

Я думаю, вам нужно понять, почему это занимает так много времени, прежде чем вы сможете найти решение для ее решения.

Проблемы с файловой системой?

  • Неужели смехотворное количество отдельных файлов замедляет процесс?

    Например, делает cat myservers/*.conf | md5 занять целую минуту?

    Если это так, вы можете захотеть использовать RAM-диск для своей конфигурации; или хранить отдельные конфигурации в базе данных и иметь один nginx.conf для перезагрузки.

Проблемы с директивой конфигурации?

  • Неужели содержимое файлов конфигурации перезагружается очень долго?

    Это могло быть проблемой по-разному.

    Например, возможно, в одной из ваших конфигураций используется доменное имя, разрешение которого занимает много времени (из-за тайм-аута), что замедляет всю перезагрузку. Это потенциально уязвимость системы безопасности в вашей настройке, так как один пользователь может замедлить всю последовательность перезагрузки при «правильном» вводе.

    Это также может быть другой проблемой конфигурации, возможно, когда нужно закрыть / открыть слишком много отдельных файлов журнала. Вы можете больше узнать об этом с помощью таких инструментов, как lsof и / или fstat, чтобы увидеть количество открытых файлов, которые принимает ваше приложение.

Это вообще настоящая проблема?

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

    Я бы сказал, что было бы вполне разумно объединить перезагрузки в пакеты и выполнять перезагрузки каждые 5-15 минут. Если вы имеете дело с новыми доменными именами, вам, вероятно, уже придется подождать, пока конфигурация не начнет работать на уровне DNS. Задержка до 1 минуты вовсе не является необоснованной и до сих пор очень часто применяется в производственных сервисах различных облачных провайдеров. Фактически, корневые зоны DNS также часто обновляются в пакетном режиме, часто по расписанию, гораздо реже, чем раз в 15 минут, особенно с учетом огромного объема задействованных данных; например, .ru обновляется только 4 раза в день, так как он имеет 5 миллионов записей и зеркалируется несколькими отдельными поставщиками для избыточности, причем каждое обновление принимает до 30 минут, следовательно, они должны быть разнесены, чтобы обеспечить разумный уровень согласованности и гарантировать, что отдельные обновления не пересекаются друг с другом.

    Если вам требуется, чтобы изменения вступили в силу немедленно, возможно, потребуется другая архитектура; может быть тот, в котором предусмотрена отдельная промежуточная область для тестирования конфигурации, или многоуровневый подход, или коммерческая версия nginx и / или сторонние плагины.


Найти выход из положения.

В зависимости от источника проблемы решение может заключаться в изменении вашей конфигурации.

Не зная источника проблемы, вопрос слишком широк, чтобы дать какой-либо конкретный совет.

Очевидный (наивный) подход - использовать рамдиск, затем настройте регулярное резервное копирование. Это может быть запланировано или вызвано каким-либо перехватчиком, например когда пользователь вносит изменения в cPanel или что-то в этом роде, запускается резервное копирование.

Вариант этого заключается в том, чтобы весь каталог обрабатывался как кеш, например vmtouch.

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

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

https://stackoverflow.com/a/14464835