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

Вступление

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

Предпосылки

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

Если вы используете Ubuntu 14.04, вы можете узнать, как настроить пользователя с правами + sudo + https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 [ Вот]. Вы можете установить Nginx, следуя th guide.

Если вы используете CentOS 7, вы можете настроить его, выполнив this guide для + sudo + пользователь, а затем this guide для установки Nginx.

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

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

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

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

  • * + USR2 + *: Это порождает новый набор основных / рабочих процессов, не затрагивая старый набор.

  • * + WINCH + *: Это говорит главному процессу Nginx, чтобы изящно остановить его связанные рабочие экземпляры.

  • * + HUP + *: Это говорит главному процессу Nginx о необходимости перечитать его файлы конфигурации и заменить рабочие процессы теми, которые придерживаются новой конфигурации. Если работает старый и новый мастер, отправка этого старому мастеру порождает рабочих, используя их исходную конфигурацию.

  • * + QUIT + *: Это изящно закрывает мастера и его работников.

  • * + TERM + *: Это инициирует быстрое отключение мастера и его работников.

  • * + KILL + *: Это немедленно убивает мастера и его работников без какой-либо очистки.

Поиск идентификаторов процессов Nginx

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

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

ps aux | grep nginx
outputroot       0.0  0.3  47564  3280 ?        S    13:26   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    10847  0.0  0.1  47936  1908 ?        S    13:26   0:00 nginx: worker process
user     10961  0.0  0.0 112640   964 pts/0    S+   13:53   0:00 grep --color=auto nginx

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

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

cat /run/nginx.pid
output

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

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

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

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

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

sudo kill -s USR2

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

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

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

ps aux | grep nginx
outputroot       0.0  0.3  47564  3280 ?        S    13:26   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    10847  0.0  0.1  47936  1908 ?        S    13:26   0:00 nginx: worker process
root       0.0  0.3  47564  3132 ?        S    13:56   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    11004  0.0  0.1  47936  1912 ?        S    13:56   0:00 nginx: worker process
user     11031  0.0  0.0 112640   960 pts/0    S+   14:01   0:00 grep --color=auto nginx

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

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


==> /run/nginx.pid.oldbin <==

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

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

Завершите работу первых мастеров

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

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

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

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

ps aux | grep nginx
outputroot       0.0  0.3  47564  3280 ?        S    13:26   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
root       0.0  0.3  47564  3132 ?        S    13:56   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    11004  0.0  0.1  47936  1912 ?        S    13:56   0:00 nginx: worker process
user     11089  0.0  0.0 112640   964 pts/0    R+   14:13   0:00 grep --color=auto nginx

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

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

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

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

Если ваше обновление прошло успешно, завершите переход

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

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

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

Если новые работники испытывают проблемы, вернитесь к старому бинарному

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

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

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

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

ps aux | grep nginx
outputroot       0.0  0.3  47564  3280 ?        S    13:26   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
root       0.0  0.3  47564  3132 ?        S    13:56   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    11004  0.0  0.1  47936  1912 ?        S    13:56   0:00 nginx: worker process
nginx    19918  0.0  0.1  47936  1900 ?        S    14:47   0:00 nginx: worker process
user     19920  0.0  0.0 112640   964 pts/0    R+   14:48   0:00 grep --color=auto nginx

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

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

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

ps aux | grep nginx
outputroot       0.0  0.3  47564  3280 ?        S    13:26   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    19918  0.0  0.1  47936  1900 ?        S    14:47   0:00 nginx: worker process
user     19935  0.0  0.0 112640   964 pts/0    R+   14:50   0:00 grep --color=auto nginx

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

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

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

Заключение

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