Лучший способ перезапустить / перезагрузить Gunicorn (через Upstart) после "git pull" мои проекты Django
Я ищу что-то лучше, чем sudo restart projectname
каждый раз, когда я выпустить git pull origin master
, который снимает мои последние изменения в проекте Django. Это restart
команда, я считаю, связана с выскочкой,которую я использую для запуска / запуска моего процесса сервера Gunicorn.
этот перезапуск вызывает короткое отключение. Пользователи, попадающие на веб-сервер (nginx), получат 500, потому что Gunicorn все еще перезапускается. На самом деле, кажется, что он перезапускается мгновенно, но для страниц требуется несколько секунд нагрузка.
любые идеи о том, как сделать это бесшовное? В идеале, я хотел бы выпустить мой git pull
и Gunicorn перезагружается автоматически.
5 ответов
для изящной перезагрузки вы должны вместо этого использовать Upstart's , например:
sudo reload jobname
согласно initctl (выскочка) manpage, reload
отправить HUP
сигнал к процессу:
reload JOB [KEY=VALUE]...
Sends the SIGHUP signal to running process of the named JOB instance.
...что для Gunicorn вызовет изящный перезапуск (см. часто задаваемые вопросы).
вы можете сказать Gunicorn перезагрузить изящно, используя HUP
сигнал вот так:
kill -HUP <pid>
(см. часто задаваемые вопросы дополнительные сведения)
я использую руководитель для управления моим сервером Gunicorn, который позволяет мне использовать этот (слегка хакерский) способ перезагрузки Gunicorn после развертывания:
supervisorctl status gunicorn | sed "s/.*[pid ]\([0-9]\+\)\,.*//" | xargs kill -HUP
вы, очевидно, могли бы добиться чего-то подобного с pidof
или ps
.
Это на самом деле бегут от ткани сценарий, поэтому мне даже не нужно входить на сервер вообще.
для тех, кто не использует supervisord: что сказал Роб, он также работает с ps,
ps aux |grep gunicorn |grep projectname | awk '{ print }' |xargs kill -HUP
Systemd, gunicorn & Ubuntu
здесь ОДН-вкладыш, если вы бежите ваше обслуживание gunicorn с systemd в.
systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$//g p' | cut -f1 -d' ' | xargs kill -HUP
детали шаг за шагом
С gunicorn docs скажите, что правильный способ изящно перезагрузить рабочих-использовать kill -HUP <Main PID>
, где <Main PID>
это идентификатор процесса главного процесса, мы извлекаем главный PID с помощью systemctl и запускаем kill -HUP <Main PID>
.
1) Сделать информация о процессе из systemd с использованием имени сервиса
systemctl status gunicorn
здесь gunicorn
- название сервиса, расположенного по адресу /etc/systemd/system/
.
пример:
ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn
● gunicorn.service - Gunicorn server for yourproject.com
Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2017-11-04 19:16:24 UTC; 1h 15min ago
Main PID: 10673 (gunicorn)
CGroup: /system.slice/gunicorn.service
├─10673 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
├─11069 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
├─11070 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
└─11071 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
Nov 04 20:27:04 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:27:04 +0000] [11047] [INFO] Booting worker with pid: 11047
Nov 04 20:27:04 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:27:04 +0000] [11048] [INFO] Booting worker with pid: 11048
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [10673] [INFO] Handling signal: hup
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [10673] [INFO] Hang up: Master
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11046] [INFO] Worker exiting (pid: 11046)
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11047] [INFO] Worker exiting (pid: 11047)
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11048] [INFO] Worker exiting (pid: 11048)
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11069] [INFO] Booting worker with pid: 11069
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11070] [INFO] Booting worker with pid: 11070
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11071] [INFO] Booting worker with pid: 11071
2) Получить идентификатор процесса (PID) основного процесса gunicorn
на sed команда работает следующим образом:sed 's/<search this>/<replace with this>/g'
-
s
средством заменить иg
означает что поиск весь вход . - на
-n
флаг сообщает sed не печатать каждую строку (или на самом деле ничего не печатать.) - на
p
в конце говорит sed для печать совпадающей строки. - мы ищем
.*Main PID: \(.*\)$
, который является шаблоном регулярного выражения, который имеет следующие части:.*
соответствует любому символу (.
) ноль или более раз (*
). Тогда мы ищемMain PID:
за ними следуют любые символы, повторяемые ноль или более раз (.*
). Чтобы захватить все символы послеMain PID:
-текст, прилагаем.*
в скобки, которые экранируются с обратными косыми чертами:\(.*\)
.$
обозначает конец строки. - " заменить на это " часть команды sed просто
, что означает первый захваченный набор символов.
пример:
ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$//g p'
10673 (gunicorn)
3) избавиться от лишних персонажи
Pipe выход к вырезать. The cut -f1 -d' '
означает, что
- строка разделена пробелом: здесь
-d
определяет разделитель, который является символом сразу после-d
. Поскольку разделителем является пробел, мы заключаем это в кавычки. -
-f
означает только то, что резка производится с помощью разделителя (а не байтов), и-f1
означает, что мы хотим вынуть первый элемент список.
пример:
ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$//g p' | cut -f1 -d' '
10673
4) Используйте основной PID
трубопровод xargs означает просто выполнение команды с аргументами из трубы с левой стороны. Поскольку мы передаем только основной PID в xargs,
systemctl status gunicorn-django | sed -n 's/.*Main PID: \(.*\)$//g p' | cut -f1 -d' ' | xargs kill -HUP
в основном то же самое как
echo <Main PID > | xargs kill -HUP
что означает
kill -HUP <Main PID >
Edit
немного более надежное решение было бы использовать cut -f1 -d$'\n'
или grep -m1 ""
перед cut -f1 -d' '
, чтобы выбрать только первую строку матч. Я не могу понять никаких обстоятельств, где было бы два матча для Main PID:
, хотя.
мы запускаем Gunicorn под надзором, но это самый простой и чистый способ, который мы нашли, чтобы изящно перезагрузить Gunicorn, когда он запутывается:
sudo pkill -HUP -f gunicorn.*master