Настройки в Nginx

7 февраля 2020

Правильно перечитываем настройки в Nginx

Проблема может показаться надуманной, потому что способ известен с незапамятных времён:

nginx -t && nginx -s reload

Его недостаток заключается в том, что конфигурация последовательно читается три раза:

  • сначала в режиме проверки из “nginx -t”;
  • затем в режиме проверки из “nginx -s reload”;
  • в случае успеха “nginx -s reload” отправляет мастер-процессу SIGHUP, и мастер-процесс также читает настройки, проверяет их, и в случае отсутствия ошибок применяет.

Этим недостатком можно пренебречь, пока размер настроек остаётся небольшим.

Однако с конфигурацией среднего (по нашим меркам) размера он начинает создавать неудобства:

$ date ; nginx -q -T | wc -l ; date
Tue Dec 17 18:57:14 MSK 2019
54651
Tue Dec 17 18:57:25 MSK 2019

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

Увы, но редкий клиент способен ждать в наше время так долго.

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

Поэтому нижнюю границу в 11 секунд будем считать предельной (это не вполне так, потому что порядок настроек способен влиять на скорость чтения, но поход в эти дебри мы отложим до следующего раза). Как её можно достичь?

Во-первых, если “nginx -s reload” выполняет проверку настроек перед отправкой сигнала мастер-процессу, становится ненужным предварительный “nginx -t”.

Во-вторых, поскольку мастер-процесс самостоятельно проверяет настройки перед применением, можно заменить “nginx -s reload” на простую отправку сигнала:

pkill -HUP -F /var/run/nginx.pid

В этом случае настройки будут читаться всего один раз.

Однако возникает проблема — как обнаруживать, что в настройки закралась ошибка и nginx не сумел их применить? Вариант с проверкой error.log отпадает, потому что Nginx сообщает там о получении сигнала и о найденных ошибках, но об отсутствии ошибок и успешном применении настроек не сообщает.

С другой стороны, что мешает нам вызвать “nginx -t” не до отправки сигнала, а после? При этом и мастер-процесс, и “nginx -t” потратят на чтение настроек по 11 секунд, но они потратят их не последовательно, а одновременно. Таким образом, за минимально возможное время мы и применим настройки, и убедимся, что они верные (а значит, применились):

pkill -HUP -F /var/run/nginx.pid  #..возвращает управление немедленно, nginx master начал перечитывать настройки
if nginx -q -t; then
    echo "В этот момент nginx master, скорее всего, уже работает с новыми настройками."
else
    echo "В новых настройках ошибка, nginx master продолжил работать со старыми."
fi


← Назад в Блог

Подпишитесь на новые статьи: