Внимание, много букв и нет картинок :).
Современные тенденции склоняются от монолитов в сторону микросервисной архитектуры. Приложения, разработанные на платформе, можно тоже отнести к сервисам или к набору сервисов. Из приведенных в методологии "Приложение двенадцати факторов" (The Twelve-Factor App) рекомендаций что-то уже нами используется. А кто-то вообще скажет: "Все это и ежику понятно!". Будем считать, что эта статья не для ежиков, а для сусликов. Для тех сусликов, которым это поможет получить новые или структурировать существующие знания для разработки еще более современных и совершенных сервисов.
Перечислим все 12 факторов, и попытаемся упрощенно переложить их на платформу и решения на ее основе. И платформа, и существующие решения на ее основе исторически во многом обладали свойствами именно монолита, но в некотором приближении попытаемся найти примеры, оценить соответствие и возможность применимости методологии к разработке на платформе.
1.Кодовая база
Одна кодовая база, отслеживаемая в системе контроля версий, – множество развёртываний.
Платформа 1С:Предприятие предоставляет собственную систему контроля версий - Хранилище конфигурации, а так же внедряются механики работы с git. Используя конфигурацию, разработанную на платформе, можно развернуть несколько экземпляров приложения.
На практике полноценной работы с git мы не имеем. Для стейджинга поднимаются не одно, а несколько хранилищ, что технически уже расходится с понятием единой кодовой базы.
2. Зависимости
Явно объявляйте и изолируйте зависимости.
Здесь подразумевается, что не стоит полагаться на повсеместное наличие всех необходимых для работы приложения компонентов. Сценарий с отсутствием компонентов или утилит должен быть предусмотрен, а для этого в составе приложения должно быть описание всех зависимостей (утилит, пакетов, библиотек) необходимых для корректной работы приложения. А лучше существование менеджера пакетов, который бы упрощал настройку приложения.
Данный пункт частично применим. Дистрибутив платформы предложит установить, например, "Microsoft Visual C++ 2015 Redistributable", но об отсутствии драйвера "MS SQL Native Client" мы узнаем уже в формате ошибки. Понятно, что вендор не знает в каком формате или на какой БД мы ходим работать. Отменяет ли это возможность наличия инструментов быстрой настройки?
В типовых решениях некоторые внешние компоненты поставляются как макеты двоичных данных в составе конфигурации.
В собственных решениях можно использовать следующее:
- дополнительные внешние библиотеки можно сохранять как макет двоичных данных в конфигурацию;
- если они требуют установки в систему, то лучше разработать механизм быстрого развертывания, позволяющий по "нажатию волшебной кнопки" осуществлять все необходимые для этого действия (regsv32, regasm, choco install или что-либо другое);
3. Конфигурация
Сохраняйте конфигурацию в среде выполнения
Необходимо разделять код приложения и настройки, которые могут меняться между разными развертываниями. Это относится, например, к реквизитам или идентификаторам доступа как внешним по отношению к инфраструктуре, так и внутренним ресурсам, параметры среды исполнения (dev, test, prod).
В платформе реквизиты подключения к внешним источникам настраиваются в среде выполнения, а не зашиваются в код или конфигурацию. Типовые решения так же реализуют отдельные хранилища для, например, подключения к ИТС.
Хранение настроек в справочниках, регистрах, константах соответствует идее разделения кода и настроек. В этом случае система должна автоматически определять окружение и брать из настроек только те значения, которые ему соответствуют. Еще лучше, если источник настроек существует в самом окружении в виде внешнего по отношению к нашей системе хранилища: файл, сервис, БД и т.д.
4. Сторонние службы (Backing Services)
Считайте сторонние службы (backing services) подключаемыми ресурсами
Любые сторонние по отношению к нашему приложению службы - это подключаемые ресурсы. Если мы перемещаем/заменяем локальный ресурс или выносим его в облако, то наше приложение должно продолжить работу - достаточно изменить настройки подключения. Ресурсы можно по необходимости отключать и подключать.
В какой-то степени платформа реализует этот подход. Например, с настройками подключения к хранилищу конфигураций, подключением ИБ в кластер, перемещение БД с одного сервера на другой. Работа с RAS и сервисы кластера так же отнесем сюда.
В решениях на платформе работой с ftp, почтой и другими внешними службами не зависит от их расположения.
5. Сборка, релиз, выполнение
Строго разделяйте стадии сборки и выполнения
Код обязательно должен пройти 3 этапа:
- этап сборки - код трансформируется в исполняемый пакет
- этап релиза - сборка объединяется с текущей конфигурацией
- этап выполнения - запуск приложения
Платформа изолирует от разработчика этапы, но фактически они существуют. Где-то очень глубоко :)
В существующих процессах можно найти аналогии:
- изменяем конфигурацию разработчика
- накатываем изменения на конфигурацию БД
- запускаем приложение
Инструменты развертывания и управления релизами для 1С - это для многих еще неизведанная область.
6. Процессы
Запускайте приложение как один или несколько процессов, не сохраняющих внутреннее состояние (stateless)
Приложение выполняется как один или несколько процессов. Процесс не сохраняет внутреннее состояние и не имеет разделяемых с другими процессами данных. Речь идет об операционных данных, используемых при выполнении конкретной работы или транзакции. К таким данным можно отнести кэш или результаты промежуточных вычислений. Любые другие данные, которые должны стать доступны параллельным процессам, необходимо отправить в сервис хранения (сохранить в БД).
По этому пункту можно провести аналогию с уровнями изоляции транзакций. Каждый процесс должен выполняться в достаточной изоляции от других процессов. Процесс может иметь промежуточный кэш, но в БД должны попасть только итоговые данные, которые могут полноценно использоваться другими процессами.
Платформа запускает несколько независимых процессов кластера. Данные, которые должны стать доступны всем процессам сохраняются в служебных файлах настроек кластера, а все остальное существует либо в памяти процессов, либо во временных файлах.
В разработанных на платформе приложениях использование многопоточной обработки данных все еще слабо распространенный прием. Фоновые задания конечно используются, но скорее именно как "задания в фоне", которые не блокируют интерактивную работу с приложением. Может быть это так из-за слабого понимания подходов к разделению данных между процессами и их синхронизации?
7. Привязка портов (Port binding)
Экспортируйте сервисы через привязку портов
Приложение должно быть самодостаточным и реализовывать внутренние сервисы без необходимости развертывания внутри себя веб-сервера. Если приложение внутри себя контейнеризирует несколько сервисов, то каждый сервис необходимо предоставлять через отдельный порт.
Платформа реализует сервисы кластера через привязку портов.
С точки зрения платформенных приложений кажется здесь обсуждать особо нечего. Публикация возможно только с использованием сторонних веб-серверов. Разнесение опубликованных сервисов по портам технически возможно.
8. Параллелизм
Масштабируйте приложение с помощью процессов
Для исполнения разного рода работы необходимо использовать отдельные процессы. Масштабируемость достигается путем запуска процессов разного типа в нескольких экземплярах. За счет свойств изоляции из п.6 обеспечивается простота и надежность параллельной работы.
В кластере есть типизация процессов: агент, менеджеры кластера, рабочие процессы. Кластер легко масштабируется горизонтально.
Решения на платформе, как уже было отмечено в п.6 не изобилуют параллельными вычислениями. Есть куда расти.
9. Утилизируемость (Disposability)
Максимизируйте надёжность с помощью быстрого запуска и корректного завершения работы
Процессы приложения могут быть быстро остановлены и перезапущены. Это обеспечивает быстрое развертывание изменений, гибкое масштабирование.
Может мне так везло, но кластер не всегда является образцовым представителем этого пункта методологии. Перезапуск службы может быть быстрым. А может и не быть. Перезапуск процессов может быть быстрым. А может и не быть. Но работа в этом направлении ведется в каждом релизе платформы, так что считаю пункт засчитан.
С приложениями на платформе история в целом та же. Перезапустить фоновые процессы, реализующие работу в конкретном приложении, иногда бывает возможно только через рестарт рабочего процесса или даже всей службы кластера. В зависимости от "тяжести" конкретного решения перезапуск клиентского приложения тоже может быть не быстрым (например, пока позакрываешь кучу рекламных окошек или новостей %)).
10. Паритет окружений разработки и продуктива (Dev/prod parity)
Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими
Необходимо обеспечивать:
- минимальное различие между кодом разработки и продакшена; например, путем увеличения частоты деплоев и использованием инструментов быстрой доставки изменений;
Понятно, что накапливать различия между кодом разработки и продакшена не стоит, на моей практике бывало всякое - это зависит от внутренних процессов команды разработки;
- к развёртыванию изменений в продакшене привлекать тех же людей, которые реализовывали изменения; тот кто делает задачу может лучше понимать специфику ее деплоя;
DevOps-инженер в среде 1С как Йети: следы есть, но толком никто не видел. Исторически сотрудники поддержки 1С были Бухгалтер-Консультант-Менеджер-Программист-Администратор-Сетевик в одном лице, так что в пункт про "привлечение одних и тех же людей" мы укладываемся %). Ну а если серьезно, то сфера 1С постепенно подтягивается к современным технологиям и тенденциям непрерывного развертывания.
- среды разработки и продакшена должны быть максимально идентичными в плане используемых стеков и инструментов; разрабатывать на Postgres, а в продакшен катить на MS SQL - это вилы;
Этот пункт в 1С прям по дефолту включен, учитывая вопрос: "А что вам еще и отдельный сервер для разработки нужен?" :)
11. Журналирование (Logs)
Рассматривайте журнал как поток событий
Необходимо рассматривать лог как поток событий в стандартный поток вывода (stdout), по которому можно отслеживать поведение приложения. Само приложение не заботится о задаче сбора данных из потока вывода и хранения собранных данных.
Считаем, что через сервис журнала регистрации платформа обеспечивает для приложения такой формат :)
При работе с фоновыми заданиями сэмулировать подобный подход можно через отправку сообщений (метод Сообщить()) и дальнейшим получением сообщений фонового задания для разбора и фиксации, и это тоже можно делать отдельным фоновым заданием. В качестве сообщений может быть не только текст, но и данные в любом формате (текст, xml, json, строка base64).
12. Задачи администрирования
Выполняйте задачи администрирования/управления с помощью разовых процессов
Для выполнения отдельных задач администрирования/управления или исполнения скриптов используются отдельные разовые процессы.
Платформа реализует, например, фоновое обновление конфигурации БД как отдельный процесс.
Приложения на платформе могут использовать фоновые задания для изоляции административных действий над системой. Ключевое слово "могут".
Что мы получаем в итоге? Рассмотрев существующие примеры можно сказать, что методология и так уже где-то рядом. По заявлению разработчиков: "Методология двенадцати факторов может быть применена для приложений, написанных на любом языке программирования". Пригодятся ли идеи описанные в методологии каждый решит сам. По моему мнению методология применима, пусть и с рядом допущений: "это же 1С!"
Подробнее почитать про методологию можно узнать из источника 12factor[точка]net или погуглив "приложение 12 факторов".