У меня есть приложение 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
прочтите второй блок, где поясняется этот флаг ...
На основе ответ 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 снова