Статьи

Django в производстве: часть 3 — автоматизация и мониторинг

Это третья часть в серии о Джанго в производстве. Если вы еще этого не сделали, сначала прочитайте часть 1 и часть 2 .

В первых двух статьях этой серии я описал основной стек, который обеспечивает работу приложения Django, и очередь задач Celery, которую можно использовать для асинхронного выполнения кода. В этом третьем посте я опишу, как можно отслеживать производственное приложение Django и как автоматизировать такие общие задачи, как развертывание.

Мониторинг приложений Django

Существует много способов мониторинга приложения Django, но особенно полезным является Graphite .

графитовый

Graphite обеспечивает визуализацию в реальном времени и хранение числовых данных временных рядов
на уровне предприятия.

Главное не бояться слова предприятия . Graphite — это относительно простая система из трех частей: Whisper — это эффективная, полностью Python-реализация базы данных циклического перебора, а Carbon — демон, который управляет базой данных Whisper и обеспечивает кэширование. Наконец, веб-приложение Graphite предоставляет интерфейс Django для данных, хранящихся в базе данных Whisper.

По общему признанию, веб-интерфейс Graphite сложен в использовании. Его функция выкупа — это мощный API на основе URL, который позволяет программно составлять графики, что в некоторой степени проще, чем навигация по сложной системе меню. Тем не менее, после освоения Graphite может производить удивительно подробную статистику о самых глубоких внутренностях вашего приложения.

Понятно, что ключ к отличным графикам — много (и много ) данных. Фактически, 37signals сообщают, что их серверы записали невероятные 100 000 000 измерений в первые 10 дней 2012 года. Эти измерения были выполнены с использованием statsd , который является демоном Node.js для сбора статистики по простому протоколу UDP и отправки ее в Graphite. ,

Statsd

Отличительной особенностью statsd является то, что он использует UDP для сбора статистики. Это означает, что клиент может быть написан практически на любом языке, и когда сервер не работает, клиент полностью не подвержен влиянию . В конце концов, статистика важна, но не настолько важна, чтобы отключить все приложение в автономном режиме, когда оно не собирается.

До сих пор не было ничего специфичного для Django (за исключением того факта, что Graphite написан на Django). Фактически, эти системы могут использоваться для мониторинга практически всего.

Тем не менее, django-statsd предоставляет очень полезный набор базовой статистики для приложений Django и настоятельно рекомендуется. Как ни странно, он устанавливается из PyPi с помощью pip install django-statsd-mozilla, так как имя уже занято другим приложением.

После установки просто включите пару классов промежуточного программного обеспечения, которые записывают каждый запрос / ответ и время их выполнения в statsd. Для более конкретной статистики, однако, клиентская библиотека очень проста в использовании:

from django_statsd.clients import statsd
statsd.incr('response.200') 

 

Интересно, что он также интегрируется с панелью django-debug-toolbar и может «обезьянить» Django для включения статистики модели / кэша — но я оставлю это как упражнение для читателя.

автоматизация

Часто в поисках наименьшего возможного усилия программисты слишком много автоматизируют. Однако, в случае развертывания приложений, что, как правило, является простой, но повторяющейся задачей, я думаю, что мы оправданы.

ткань

Если вы еще этого не сделали, вам следует потратить некоторое время на чтение о Fabric . По сути, это библиотека Python, которая позволяет создавать команды SSH, независимо от того, находятся ли они на одном или нескольких удаленных хостах.

Fabric — это библиотека Python и инструмент командной строки для оптимизации использования
SSH для развертывания приложений или задач системного администрирования.

Fabric использует файл на верхнем уровне проекта, который называется fabfile.py, чтобы определить функции, которые можно использовать в командной строке.

Есть несколько очень полных примеров «fabfiles», которые можно использовать для развертывания Django, таких как Gareth Rushgrove .

Для моих проектов, в которых используется только один сервер, я использую более упрощенную версию:

import os
from fabric.api import env, require, run, sudo, cd

env.project_name = ''
env.server_name = ''
env.webapps_root = '/opt/webapps/'

env.project_root = os.path.join(env.webapps_root, env.project_name)
env.activate_script = os.path.join(env.project_root, 'env/bin/activate')
env.wsgi_file = os.path.join(env.project_root, 'django.wsgi')
env.repo_root = os.path.join(env.project_root, 'repository')
env.search_index = os.path.join(env.project_root, 'search_index')
env.requirements_file = os.path.join(env.repo_root, 'requirements.txt')
env.manage_dir = os.path.join(env.repo_root, env.project_name)

def production():
    env.hosts = [env.server_name]
prod = production

def virtualenv(command, use_sudo=False):
    if use_sudo:
        func = sudo
    else:
        func = run
    func('source "%s" && %s' % (env.activate_script, command))

def update():
    require('hosts', provided_by=[production])
    with cd(env.repo_root):
        run('git pull origin master')

def install_requirements():
    require('hosts', provided_by=[production])
    virtualenv('pip install -q -r %(requirements_file)s' % env)

def manage_py(command, use_sudo=False):
    require('hosts', provided_by=[production])
    with cd(env.manage_dir):
        virtualenv('python manage.py %s' % command, use_sudo)

def syncdb(app=None):
    require('hosts', provided_by=[production])
    manage_py('syncdb --noinput')

def migrate():
    require('hosts', provided_by=[production])
    manage_py('migrate')

def rebuild_index():
    require('hosts', provided_by=[production])
    manage_py('rebuild_index --noinput', use_sudo=True)
    sudo('chown -R www-data:www-data %(search_index)s' % env)

def collectstatic():
    require('hosts', provided_by=[production])
    manage_py('collectstatic -l --noinput')

def reload():
    require('hosts', provided_by=[production])
    sudo('supervisorctl status | grep %(project_name)s '
         '| sed "s/.*[pid ]\([0-9]\+\)\,.*/\\1/" '
         '| xargs kill -HUP' % env)

def deploy():
    require('hosts', provided_by=[production])
    update()
    install_requirements()
    syncdb()
    migrate()
    collectstatic()
    reload()

Как вы, вероятно, можете сказать из кода, при нажатии кнопки выполняются следующие операции:

  • Обновляет Git-репозиторий сервера
  • Устанавливает любые новые требования с pip
  • Синхронизирует базу данных для создания любых новых таблиц
  • Выполняет любые миграции на юг, которые еще не были проведены
  • Связывает любой статический носитель
  • Перезагрузка веб-сервера (см. Часть 1 для настройки Gunicorn)

Как только этот файл будет создан, выполнение fab prod deploy из любой точки исходного дерева проекта автоматически развернет последний код на веб-сервере за считанные секунды. Аутентификация с открытым ключом даже не запрашивает пароль. Насколько я понимаю, это того стоит!

 

Источник: http://www.robgolding.com/blog/2012/01/14/django-in-production-part-3—automation-and-monitoring/