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

Есть ли способ определить, когда nginx завершил корректное завершение работы?

У меня есть приложение ruby ​​on rails, которое работает на пассажирском и nginx, с одним основным веб-сервером и несколькими серверами приложений. Я пытаюсь обновить процесс развертывания, чтобы минимизировать (или, в идеале, удалить) любое время простоя, вызванное развертыванием. Основным препятствием на данный момент является то, что пассажиру требуется некоторое время для перезапуска (т. Е. Перезагрузки приложения), поэтому, чтобы обойти это, я хочу чередовать перезапуски, чтобы одновременно перезапускался только один сервер приложений.

Чтобы сделать это без потери каких-либо длительных процессов пассажира, я думаю, мне нужно корректно завершить работу экземпляра сервера приложений nginx, что приведет к тому, что он больше не будет принимать новые соединения, но продолжит обрабатывать существующие; Кроме того, HAProxy обнаружит, что сервер приложений не работает, и перенаправит новые запросы на другой сервер.

Однако, предполагая, что существует длительный процесс, я не уверен, как определить, когда плавное завершение работы завершено, чтобы я мог запустить его обратно. Поскольку выключение вызвано отправкой сигнала (т.е. kill -QUIT $( cat /var/run/nginx.pid )), и команда kill вернется немедленно, я не могу комбинировать команды (т.е. kill ... && touch restarted), поскольку touch Команда будет выполнена немедленно, даже если nginx не завершил свою работу.

Есть ли хороший способ сделать это?

А что насчет этого?

while [ -n "$(pgrep nginx)" ]
do
  some-stuff  
done

Итак, pgrep будет искать любые процессы nginx, а цикл while позволит ему оставаться там, пока все они не исчезнут. Вы можете изменить что-нибудь, чтобы сделать что-нибудь полезное, например sleep 1; /etc/init.d/nginx stop, чтобы он заснул на секунду, а затем попытайтесь остановить nginx с помощью сценария init.d. Вы также можете разместить там счетчик, чтобы вы могли подавать сигналы об убийстве, если это займет слишком много времени.

Почему бы не использовать для этого встроенный флаг?

nginx -s quit

прочтите второй блок, где поясняется этот флаг ...

http://nginx.org/en/docs/control.html

На основе ответ cjcВот созданный мной сценарий bash на случай, если кто-то еще столкнется с такой же проблемой:

#!/bin/bash
set -e

if [[ $(/usr/bin/id -u) -ne 0 ]]; then
  echo "This script must be run as root."
  exit
fi

if [ -n "$(pgrep nginx)" -a -f /var/run/nginx.pid ]; then
  PID=$( cat /var/run/nginx.pid )

  # Gracefully shutdown nginx
  kill -QUIT $PID

  # Wait for nginx to stop
  while [ -d "/proc/$PID" -a -f /var/run/nginx.pid ]; do
    sleep 1
  done

  # Restart nginx
  /usr/sbin/service nginx start
else
  echo "nginx is not running."
  exit 1
fi

Вы можете проверить, существует ли / proc / $ (cat /var/run/nginx.pid) /. Или попробуйте проверить, удаляется ли /var/run/nginx.pid при завершении работы.

пс -fC nginx

  root       7146     1  0 02:19 ?   00:00:00 nginx: master process /usr/sbin/nginx
  1. www     7147  7146  0 02:19 ?   00:00:00 nginx: worker process
  2. www     7148  7146  0 02:19 ?   00:00:00 nginx: worker process

поэтому, если вы напишете сценарий выключения / перезапуска, который будет повторяться до тех пор, пока в этом случае 7146 не умрет, перезапустите nginx снова