Доброго пятничного вечера! Исключительно блога ради и в виде заметки расскажу про свои приключения с gunicorn. Если вдруг кто-то не в курсе (?) gunicorn — это такой WSGI-сервер для python-приложений. Тех самых приложений, которые Flask или Django.
Замечу, что данный этап серпентологии питономании у меня предсказуемо начался с настольных приложений на tkinter gui и только потом я перелез на Flask. Например, сейчас разбираюсь с модульными приложениями на BluePrint и перевожу функционал вот этого чуда на веб-рельсы.
На момент написания этого поста (прошу не путать с моментом публикации) на рабочем веб-сервере крутится 3 приложения на gunicorn. И при всём этом я даже ещё не начинал тратить время на строительство цепочек проксирования маршрутов на nginx и продолжаю вешать приложения прямо на порты. Благо портов много и есть где разгуляться.
Болтология закончилась, теперь немного практического. Приложения в среде веб-сервера я запускаю с помощью bash-скрипта, который мирно гостит в расписании crontab. Вот примерный код скрипта, который выполняется сразу после включения или перезапуска сервера:
#!/bin/bash # Приложение №1 # PYTHONPATH=/apps/phonebook gunicorn3 --bind 0.0.0.0:8000 --workers=4 --threads=2 --timeout=60 --keep-alive=5 --daemon phonebook:app # Приложение №2 # PYTHONPATH=/apps/anketa gunicorn3 --bind 0.0.0.0:8001 --workers=4 --threads=2 --timeout=60 --keep-alive=5 --daemon anketa:app # Приложение №3 # PYTHONPATH=/apps/uploads gunicorn3 --bind 0.0.0.0:8002 --workers=4 --threads=2 --timeout=60 --keep-alive=5 --daemon uploads:app
Конфигурация запуска веб-сервера везде одинакова: сервер в виде службы вещает приложение на весь спектр доступных IP-адресов устройства, каждому приложению установлено по 4 воркера с двумя потоками.
Теперь рассмотрим конфигурацию crontab:
Директива @reboot сообщает планировщику, что скрипт нужно запустить при старте системы.
Напоминаю, что вызвать редактор планировщика в Linux можно командой crontab -e.
Запустить приложение — запустили. Теперь попробуем его остановить, не трогая работу других приложений сервера gunicorn. Конечно, если известны имена всех запущенных приложений — то команда будет до безобразия проста. Например, так можно остановить приложение anketa:
pkill -f "gunicorn3.*anketa:app"
Но, что делать если имена приложений неизвестны? Для этого попробуем покопаться в процессах системы. В частности, в запущенных процессах сервера gunicorn:
ps aux | grep gunicorn
В терминал вернётся что-то наподобие вот этого:

Допустим нам нужно отключить приложение userevents. Продолжаем грепать вывод по названию нужного приложения:
ps aux | grep gunicorn | grep userevents
Теперь мы получили id нужного процесса:

Отправляем сигнал SIGTERM (15) главному процессу приложения:
kill -15 317848
И проверяем — всё ли правильно сделали:

В терминал вернулась пустота после повторного grep. Значит нам успешно удалось «уронить» приложение userevents.
Теперь можно провести все необходимые действия с приложением и запустить его командой из bash-скрипта, чтобы не перезапускать весь сервер:
PYTHONPATH=/apps/userevents gunicorn3 --bind 0.0.0.0:8002 --workers=4 --threads=2 --timeout=60 --keep-alive=5 --daemon userevents:app
После запуска приложения можете повторить:
ps aux | grep gunicorn | grep userevents
Если всё прошло успешно в консоль вернётся перечень процессов сервера с заветным приложением.
PS.: для большей гибкости процесса рекомендую для каждого приложения свой скрипт и свою строку в планировщике.
