Как стать автором
Обновить

Плавный перезапуск FastCGI-процессов — django_graceful

Время на прочтение3 мин
Количество просмотров3.2K
Из всех способов деплоинга django-проектов мой любимый — FastCGI. Он поддерживается большинством веб-серверов, позволяет внятно разграничить права доступа и имеет массу других преимуществ.

Однако в django его реализация не лишена недостатков. Чтобы запустить FastCGI-сервер нужно выполнить «./manage.py runfcgi» с немаленьким количеством параметров, которые если и можно запомнить, то точно не захочется писать каждый раз руками. А если это происходит в контексте обновления кода проекта на боевом сервере, то команд становится ещё больше. Приходится писать различные wrapper-ы для запуска и перезапуска, которые засоряют проект.

Кстати, перезапуск, который мы выполняем для обновления кода, сопряжен ещё с одной проблемой. В django не предусмотрен плавный перезапуск FastCGI-сервера. Можно только убить старый процесс, а потом запустить новый. Происходит это не мгновенно, так что в интервал времени между смертью старого процесса и открытием порта новым процессом посетители видят ошибку 502, что, конечно, не повышает степень их доверия вашему сайту. Приходится придумывать различные хитрости и усложнять wrapper-скрипты.

Из одного из таких скриптов выросло довольно универсальное приложение django_graceful, которое решает все эти проблемы. Его идея проста: настройки FastCGI хранятся в файле settings.py, а для управления FastCGI-процессами используются простые команды из manage.py. Эти команды поддерживают несколько параллельно запущенных экземпляров FastCGI-сервера и позволяют переключать веб-сервер между ними с помощью символической ссылки на файл unix-socket-а, то есть без перезапуска веб-сервера.

Как раз это обстоятельство позволяет провернуть такой фокус: когда нам нужно обновить код, мы одной командой перезапускаем FastCGI-процесс, к которому веб-сервер в данный момент не обращается, а затем, когда он снова готов обслуживать запросы, переключаем символическую ссылку на него. Клиенты, подключившиеся до переключения, продолжают обслуживаться первым FastCGI-сервером, а новые — вторым. Для этого действия даже не нужны права администратора сервера. Тесты показали, что перерыва в обслуживании не произойдёт даже при очень плотном потоке запросов. К слову, приложение впервые было использовано на проекте о зарубежной недвижимости Tranio.Ru и до сих пор прекрасно там работает.

Как его установить?

  1. Само приложение можно скачать и установить командой easy_install django_graceful.
  2. Затем название приложения «django_graceful» нужно добавить в список INSTALLED_APPS вашего проекта.
  3. В файле settings.py нужно добавить ещё одну опцию — GRACEFUL_STATEDIR. Она должна содержать абсолютный путь к папке, где будут храниться .pid- и .socket-файлы FastCGI-процессов.
  4. Также в settings.py можно добавить словарь GRACEFUL_OPTIONS, указав в нём дополнительные опции для команды «./manage.py runfcgi».
  5. В папке GRACEFUL_STATEDIR будет создана символическая ссылка «fastcgi.socket», путь к которой нужно прописать в конфигурации веб-сервера. Например «FastCGI_pass unix:/home/web/project/var/run/fastcgi.socket» в nginx.

Как пользоваться


Перечислим типичные задачи, выполнение которых упрощает django_graceful.

Первоначальный запуск и поддержка FastCGI-сервера в запущенном состоянии:

./manage.py keepalive —команда, которая проверяет, запущен ли хотя бы один FastCGI-процесс и указывает ли на него ссылка. Если ни одного процесса не запущено, она запускает первый. Если ссылка указывает на незапущенный процесс, команда переключает её на сокет запущенного процесса. Иначе, то она не делает ничего.

Я люблю добавлять эту команду в crontab для выполнения раз в минуту. Она поднимет FastCGI после непредвиденного падения или внеплановой перезагрузки сервера.

Плавный перезапуск FastCGI после обновления кода:

./manage.py update —команда, которая выполняет описанный выше фокус с перезапуском неактивного FastCGI-процесса и установкой на него ссылки.

Полный список команд

  • start — запускает выбранные процессы;
  • stop — останавливает выбранные процессы;
  • switch — переключает символическую ссылку на указанный процесс;
  • keepalive — проверяет, есть ли хотя бы один запущенный и активный процесс;
  • restart — перезапускает указанные процессы;
  • status — показывает статусы процессов;
  • update — перезапускает неактивный процесс и устанавливает на него ссылку;


Вот и всё! Это приложение живёт по адресу github.com/andreiko/django_graceful
Удобного вам деплоинга и высокого аптайма :)
Теги:
Хабы:
+47
Комментарии29

Публикации

Истории

Работа

Python разработчик
142 вакансии

Ближайшие события