Systemd, gunicorn & Ubuntu
Это однострочник, если вы используете службу gunicorn с systemd .
systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$/\1/g p' | cut -f1 -d' ' | xargs kill -HUP
Подробнеешаг за шагом
Поскольку документация gunicorn говорит о том, что правильный способ корректной перезагрузки рабочих заключается в использовании 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
The sed команда работает следующим образом: sed 's/<search this>/<replace with this>/g'
s
означает команду замену , а g
означает, чтопоиск по всему вводу глобально . - Флаг
-n
указывает sed не печатать каждую строку (или фактически, нет)чтобы напечатать что-нибудь.) p
в конце говорит sed для напечатать совпавшую строку . - Мы ищем
.*Main PID: \(.*\)$
, которое является регулярным выражениемшаблон, который состоит из следующих частей: .*
соответствует любому символу (.
) ноль или более раз (*
).Затем мы ищем Main PID:
, за которым следуют любые символы, повторяемые ноль или более раз (.*
).Чтобы захватить все символы после Main PID:
-текста, мы заключаем .*
в круглые скобки, которые экранируются обратной косой чертой: \(.*\)
.$
указывает на конец строки. - Часть команды sed для замены "only this" - это просто
\1
, что означает первый захваченный набор символов.
Пример вывода:
ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$/\1/g p'
10673 (gunicorn)
3) Избавьтесь от лишних символов
Передайте вывод в cut .cut -f1 -d' '
означает, что
- Строка разделена пробелом: Здесь
-d
определяет разделитель, который определяется сразу после -d
.Поскольку разделитель - это пробел, мы заключаем его в кавычки. -f
означает, что вырезка выполняется только с использованием разделителя (а не байтов), а -f1
означает, что мы хотим вынуть первыйэлемент списка.
Пример вывода:
ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$/\1/g p' | cut -f1 -d' '
10673
4) Использовать основной PID
Piping to xargs означает просто запусккоманда с аргументами из трубы на левой стороне.Поскольку мы передаем только основной PID в xargs,
systemctl status gunicorn-django | sed -n 's/.*Main PID: \(.*\)$/\1/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:
, хотя.