Поиск по сайту:

Как обновить Nginx на месте без разрыва клиентских подключений


Введение

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

Предпосылки

Прежде чем приступить к этому руководству, на вашем сервере должен быть пользователь без полномочий root, настроенный с привилегиями sudo. Вам также потребуется установить Nginx.

Вы можете следить за установкой Nginx на этот сервер.

Как работает обновление

Nginx работает, создавая главный процесс при запуске службы. Главный сервис, в свою очередь, порождает один или несколько рабочих процессов, которые обрабатывают фактические клиентские подключения. Nginx предназначен для выполнения определенных действий при получении определенных низкоуровневых сигналов от системы. Использование этих сигналов дает вам возможность обновить Nginx или его конфигурацию на месте без потери клиентских подключений.

Предоставленные Nginx сценарии установки и обновления предназначены для отправки этих сигналов при запуске, остановке и перезапуске Nginx. Однако отправка этих сигналов вручную позволяет проверить обновление и быстро вернуться в случае возникновения проблем. Это также предоставит возможность изящного обновления, если вы установили Nginx из исходного кода или не полагаетесь на менеджер пакетов для настройки службы.

Будут использоваться следующие сигналы:

  • USR2: порождает новый набор основных/рабочих процессов, не затрагивая старый набор.
  • WINCH: указывает главному процессу Nginx корректно остановить связанные с ним рабочие экземпляры.
  • HUP: это говорит главному процессу Nginx перечитать свои файлы конфигурации и заменить рабочие процессы теми, которые придерживаются новой конфигурации. Если запущены старый и новый мастер, отправка этого на старый мастер приведет к созданию рабочих процессов с их исходной конфигурацией.
  • ВЫХОД: корректно завершает мастер и его рабочие процессы.
  • TERM: инициирует быстрое завершение работы мастера и его рабочих процессов.
  • KILL: немедленно убивает мастер и его рабочие процессы без какой-либо очистки.

Поиск PID процесса Nginx

Чтобы отправлять сигналы различным процессам, нам нужно знать PID для целевого процесса. Есть два способа найти это.

Сначала вы можете использовать утилиту ps, а затем среди результатов grep для Nginx. Это позволяет увидеть главные и рабочие процессы:

  1. ps aux | grep nginx
output
root 16653 0.0 0.2 119160 2172 ? Ss 21:48 0:00 nginx: master process /usr/sbin/nginx nginx 16654 0.0 0.9 151820 8156 ? S 21:48 0:00 nginx: worker process sammy 16688 0.0 0.1 221928 1164 pts/0 S+ 21:48 0:00 grep --color=auto nginx

Второй выделенный столбец содержит PID для выбранных процессов. В последнем столбце поясняется, что первым результатом является главный процесс Nginx.

Другой способ узнать PID главного процесса Nginx — распечатать содержимое файла /run/nginx.pid:

  1. cat /run/nginx.pid
output
16653

Если запущено два главных процесса Nginx, старый будет перемещен в /run/nginx.pid.oldbin.

Создайте новый набор мастеров/воркеров Nginx

Первым шагом к изящному обновлению является фактическое обновление вашего пакета Nginx и/или двоичных файлов. Сделайте это, используя любой метод, подходящий для вашей установки Nginx, будь то через диспетчер пакетов или исходную установку.

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

Вы можете сделать это, отправив сигнал USR2 непосредственно на запрошенный вами номер PID (не забудьте указать здесь PID вашего собственного главного процесса Nginx):

  1. sudo kill -s USR2 16653

Или вы можете прочитать и подставить значение, хранящееся в вашем файле PID, непосредственно в команду, например:

  1. sudo kill -s USR2 `cat /run/nginx.pid`

Если вы проверите свои запущенные процессы, вы увидите, что теперь у вас есть два набора мастеров и рабочих Nginx:

  1. ps aux | grep nginx
output
root 16653 0.0 0.2 119160 2172 ? Ss 21:48 0:00 nginx: master process /usr/sbin/nginx nginx 16654 0.0 0.9 151820 8156 ? S 21:48 0:00 nginx: worker process root 16699 0.0 1.5 119164 12732 ? S 21:54 0:00 nginx: master process /usr/sbin/nginx nginx 16700 0.0 0.9 151804 8008 ? S 21:54 0:00 nginx: worker process sammy 16726 0.0 0.1 221928 1148 pts/0 R+ 21:55 0:00 grep --color=auto nginx

Вы также можете видеть, что исходный файл /run/nginx.pid был перемещен в /run/nginx.pid.oldbin, а PID более нового главного процесса был записан в /run/nginx.pid:

  1. tail -n +1 /run/nginx.pid*
output
==> /run/nginx.pid <== 16699 ==> /run/nginx.pid.oldbin <== 16653

Теперь вы можете отправлять сигналы любому из основных процессов, используя PID, содержащиеся в этих файлах.

На данный момент оба основных/рабочих набора работают и могут обслуживать клиентские запросы. Первый набор использует исходный исполняемый файл и конфигурацию Nginx, а второй набор использует более новые версии. Они могут продолжать работать бок о бок, но для согласованности мы должны начать переход на новый набор.

Уволить первых мастеров

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

Остановите рабочие процессы исходного набора, отправив сигнал WINCH их основному процессу:

  1. sudo kill -s WINCH `cat /run/nginx.pid.oldbin`

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

  1. ps aux | grep nginx
output
root 16653 0.0 0.2 119160 2172 ? Ss 21:48 0:00 nginx: master process /usr/sbin/nginx root 16699 0.0 1.5 119164 12732 ? S 21:54 0:00 nginx: master process /usr/sbin/nginx nginx 16700 0.0 0.9 151804 8008 ? S 21:54 0:00 nginx: worker process sammy 16755 0.0 0.1 221928 1196 pts/0 R+ 21:56 0:00 grep --color=auto nginx

Это позволяет вам проверять новых рабочих процессов, поскольку они принимают соединения изолированно.

Оцените результат и сделайте следующие шаги

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

Ваш следующий шаг будет полностью зависеть от того, столкнетесь ли вы с проблемами.

Если ваше обновление прошло успешно

Если у вас не возникло проблем с рабочими процессами вашего нового набора, вы можете безопасно закрыть старый мастер-процесс. Для этого отправьте старому мастеру сигнал QUIT:

  1. sudo kill -s QUIT `cat /run/nginx.pid.oldbin`

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

Если ваше обновление было неудачным

Если у вашего нового набора воркеров возникли проблемы, вы можете вернуться к старой конфигурации и бинарному файлу. Это возможно, если вы не ВЫЙТИ из старого главного процесса.

Лучший способ сделать это — перезапустить воркеры вашего старого мастера, отправив ему сигнал HUP. Обычно, когда вы отправляете мастеру Nginx сигнал HUP, он перечитывает свои файлы конфигурации и запускает новые рабочие процессы. Однако, когда целью является более старый мастер, он будет порождать новых рабочих, используя свою исходную рабочую конфигурацию:

  1. sudo kill -s HUP `cat /run/nginx.pid.oldbin`

Теперь вы должны вернуться к двум наборам основных/рабочих процессов:

  1. ps aux | grep nginx
output
root 16653 0.0 0.2 119160 2172 ? Ss 21:48 0:00 nginx: master process /usr/sbin/nginx nginx 16654 0.0 0.9 151820 8156 ? S 21:48 0:00 nginx: worker process root 16699 0.0 1.5 119164 12732 ? S 21:54 0:00 nginx: master process /usr/sbin/nginx nginx 16700 0.0 0.9 151804 8008 ? S 21:54 0:00 nginx: worker process sammy 16726 0.0 0.1 221928 1148 pts/0 R+ 21:55 0:00 grep --color=auto nginx

Новейшие рабочие связаны со старым хозяином. В этот момент оба рабочих набора будут принимать клиентские подключения. Теперь остановите более новый основной процесс с ошибками и его рабочие процессы, отправив сигнал QUIT:

  1. sudo kill -s QUIT `cat /run/nginx.pid`

Вы должны вернуться к своему старому хозяину и рабочим:

  1. ps aux | grep nginx
output
root 16653 0.0 0.2 119160 2172 ? Ss 21:48 0:00 nginx: master process /usr/sbin/nginx nginx 16654 0.0 0.9 151820 8156 ? S 21:48 0:00 nginx: worker process sammy 16688 0.0 0.1 221928 1164 pts/0 S+ 21:48 0:00 grep --color=auto nginx

Исходный мастер восстановит файл /run/nginx.pid для своего PID.

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

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

Заключение

К настоящему времени вы должны иметь возможность беспрепятственно переводить свои машины с одного двоичного файла Nginx на другой. Способность Nginx обрабатывать два набора master/workers, сохраняя при этом информацию об их взаимосвязях, дает нам возможность обновлять серверное программное обеспечение, не отключая серверные машины.