Простыми словами о Twelve-Factor App

    Известный провайдер heroku поддерживает манифест, который называется «12-факторное приложение» (Twelve-Factor App). Это набор лучших практик для разработки современных веб приложений на любой платформе. Практики описывают приложения, которые готовы:
    • к горизонтальному масштабированию;
    • к непрерывному развертыванию;
    • к современным облачным хостингам.

    Можно считать, что манифест отчасти рекламный — 12-факторные приложения удобней всего разворачивать на heroku. Но поскольку, манифест становиться все популярней, то часть облачных провайдеров включают лучшие практики в свое окружение, и эти практики будут полезны как разработчикам, так и тем, кто разворачивает и администрирует приложения.

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


    Одно приложение — один репозиторий


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

    Если у вас несколько приложений используют общий код, то общий код надо выделить в отдельную библиотеку, и объявить ее как зависимость. Если на каком-нибудь этапе разработки, у вас в одном репозитории лежит несколько слабосвязанных приложений, то вы должны разделить приложение на несколько, каждое из которых должно быть 12-факторным приложением.

    Явные зависимости


    Приложения не должны иметь неявных зависимостей. Во-первых, все зависимости как системные, так и библиотеки должны быть прописаны в манифесте зависимостей. Все современные языки предоставляю менеджер пакетов с манифестом зависимостей. Кроме этого зависимости должны быть изолированные, чтобы системная библиотека «не просочилась» в приложений.

    Так в Ruby использует Gemfile как формат манифеста для объявления зависимостей, bundle exec – для изоляции зависимостей. Кроме одинаковой работы приложения на разных платформах, это позволит новым разработчикам быстрее включаться в проект, или быстрее подключать новые зависимости.

    Тут следует упомянуть Docker, который изолирует и явно объявляет даже зависти ОС.

    Конфигурация — это свойства среды выполнения


    Конфигурация — это все параметры, которые меняются в зависимости от того где запущено приложение:
    • логины, пароли и адреса баз данных;
    • сторонние сервисы и ключи АПИ.

    Код не зависит от окружения, а конфигурация зависит. Поэтому код должен храниться в репозитории, а конфигурация в окружении. Если вы можете опубликовать свой код в открытый доступ без компрометации персональных учетных записей – вы все делаете правильно.

    Довольно популярный вариант – это использование заранее подготовленных наборов конфигурации (development, test и production). Такое разделение нельзя считать хорошим решением, так как добавление новых окружений (development-joe, qa, staging) непропорционально увеличивает количество параметров, которые надо поддерживать.

    Локальные и сторонние службы


    Сторонние службы — это базы данных, почтовые службы, кешурующие сервера и API различных сервисов. 12-факторное приложение не должно делать различие между локальными и удаленными службами. Каждая служба — это подключаемый ресурс, данные для подключения к которому (адрес и учетные данные) должны храниться в конфигурации.

    Замена локальной базы на Amazon RDS, или замена локального почтового сервера на сторонний, не должно влиять на код приложения.

    Разделение сборки, релиза и выполнения


    Развертывание приложения состоит из трех раздельных этапов:
    1. Сборка – это преобразование кода в исполняемый пакет — загрузка зависимостей, компиляция файлов и ресурсов.
    2. Релиз – объединение сборки с конфигурацией. Релиз сразу готов к запуску в среде исполнения.
    3. Выполнение – запуск некоторого количества процессов из релиза.

    При разработке приложения 12 факторов надо строго разделять эти этапы. Сборка инициируется разработчиком, когда он готов выложить изменения. Это может быть более длительный процесс, но после этого изменения в коде релиза внести нельзя. С другой стороны, этап выполнения должен быть как можно более простой операцией, чтобы она могла быть произведена автоматически в случае остановки оборудования, или других ошибок, без вмешательства разработчика.

    Приложение – набор процессов


    Приложение должно запускать как один или несколько процессов, которые не сохраняют свое внутреннее состояние. Приложение может использовать данные в оперативной памяти или на диске как временное хранилище. Например, при перекодировании изображений. Но любые пользовательские данные должны лежать в постоянном хранилище (подключаемом ресурсе).

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

    Приложение не зависит от сервера


    PHP-приложение может быть запущено как модуль внутри Apache HTTPD, или Java-приложение может быть запущено внутри Tomcat. Напротив, 12 факторное приложение — является полностью самодостаточным, и не полагается на наличие веб-сервера.

    Это обычно реализуется с помощью объявления зависимости для добавления библиотеки веб-сервера к приложению такой, как Tornado в Python, Thin в Ruby, Jetty в Java и ReactPHP в PHP.

    Масштаб с помощью процессов


    Обработкой разных задач должны заниматься разные процессы. Например, HTTP-запросы могут быть обработаны веб процессом, а длительные фоновые задачи обработаны рабочим процессом. Это позволит в будущем масштабировать только те процессы, которые необходимо.

    Важно, что процессы не должны демонизироваться (должны выполняться, а не запускаться). Менеджер процессов должен контролировать поток вывода приложения и реагировать на ошибки и падения процесса.

    Быстрый запуск и корректное завершение


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

    Фоновые процессы должны возвращать текущую задачу в очередь, а процессы обработки запросов корректно заканчивать запросы. Каждая задача любого процесса должна быть доступна для повторного выполнения (например, используя транзакции).

    Приблизьте разработку к развертыванию



    Сейчас между разработкой и развертыванием существует значительная разница — это делают разные люди, в разное время и разными инструментами. При внедрении 12 факторов надо стараться сделать разработку и развертывание как можно ближе:
    • Время – код должен попадать в рабочую версию через несколько часов после того, как разработчик его написал.
    • Люди – разработчик должен принимать участие в развертывание своего кода и следить за его работой в работе.
    • Инструменты – среда разработки должна максимально соответствовать среде тестирования (сторонние службы, ОС).


    Логи в stdout


    Лог — это поток событий, и надо обращаться к нему как к потоку событий. Приложение, не должно само записывать данные в файл логов, и тем более управлять файлами (архивировать или удалять).12 факторное приложение выводит лог своей работы в stdout. Менеджер, которой запускает процесс, должен направлять логии систему анализа или архивирования.

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

    В окружении разработчика логи просто просматриваются в консоле.

    Задачи администрирования


    Разовые процессы администрирования (миграции, исправления базы) должны подчиняться тем же правилам, что и остальные процессы:
    • Код задач должен лежать в репозитории, чтобы соответствовать коду основного приложения
    • Зависимости должны быть объявлены в основном манифесте зависимостей, чтобы процесс мог быть выполнен при обычном развертывании
    • Конфигурация задачи должна находиться в переменных окружения, чтобы ее можно было выполнить в разных окружениях
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 1
    • 0
      deis тоже использует эту методологию — довольно успешно

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.