Большинство IT-продуктов для наших заказчиков начинаются с модульной разработки. Часть из них со временем эволюционируют до микросервисов. Для другой части микросервисы не нужны. В этой статье мы рассмотрим, почему это именно так, и какие критерии помогают определиться: нужно ли внедрять микросервисы или стоит придерживаться работы с модулями?
Микросервисная и модульная системы — это типы архитектуры IT-решений.
- При работе с модулями дорабатывается коробочная версия существующего IT-продукта. Коробочная версия - это монолит, готовая система с ядром, которая поставляется всем заказчикам одинаково, «как есть». Доработка состоит в создании модулей с недостающим функционалом. Новые модули получаются путём переиспользования частей монолита (ядра или других модулей). Бизнес-логика прописывается внутри монолита: для программы (приложения, сайта, портала) есть одна точка входа и одна точка выхода.
- При работе с микросервисами создается IT-продукт с нуля, составляя его из «кирпичиков» — атомарных микросервисов, отвечающих за отдельный небольшой процесс (отправить письмо, получить данные по заказу, сменить статус заказа, создать клиента и т.п.).
Набор таких блоков объединяется бизнес-логикой в общую систему (например, с помощью BPMS). Несмотря на наличие связей, каждый блок автономен и имеет свои точки входа и выхода.
Преимущества модульной архитектуры
Коробочные версии есть у всех CMS- («Битрикс», Magento, Drupal, Hybris и т.д.), CRM-, ERP-, WMS- и многих других систем. Они хорошо продаются, и на них есть высокий спрос.
Рассмотрим причины, по которым заказчики чаще всего выбирают работу с модульной архитектурой и охотно покупают коробочные решения.
1. Высокая скорость внедрения.
Установка, настройка и заполнение справочников для такого ПО занимают немного времени.
Для компании среднего бизнеса реально приступить к работе с «коробкой» через три-четыре месяца после старта.
Для малого бизнеса это может быть всего несколько дней.
2. Доступная цена.
Некоторые продукты могут быть вообще бесплатны. Конечно, это не касается высоконагруженных проектов и enterprise-решений со сложной логикой.
3. Для многих задач достаточно готового функционала.
В коробочных версиях заложено много готового функционала. Для неключевых задач бизнеса вполне подойдёт софт из коробки. Например, если вам нужно поставить программу для инвентаризации, но инвентаризация — не приоритетная задача вашего бизнеса, и вы не планируете получать прибыль за счёт этого действия, вам достаточно будет коробочного решения;
4. Пусть небольшая, но вариативность.
Обычно продукт из коробки представлен в двух или более модификациях с разным функционалом. Для разных типов бизнеса, масштабов компании и прочих условий подбираются разные модификации.
Проблемы модульных систем
Основная проблема в том, что все модульные системы не предназначены для серьёзного переопределения функционала. У них есть «коробка», готовые модули — вот ими лучше и пользоваться.
Чем ближе к уровню Enterprise размеры проекта и сложность их кастомизаций, тем больше проблем с доработкой модулей. Вот основные из них:
Проблема № 1. Ядро системы становится точкой замедления, а модульность — лишним усложнением
Допустим, ваш проект связан со сложной логикой складов. Если вы выбрали модульную архитектуру, то разработчикам нужно не просто создать функционал для управления этими складами. Им нужно переопределить или расширить модуль мультискладов, который, в свою очередь, пользуется методами ядра.
При этом необходимо учесть сложную логику возвратов по складам: зависимость от событий из CRM-системы, перемещение товара между каталогами и т.д. А также скрытую логику, которая связана с возвратом денежных средств, бонусных баллов и т.д.
Когда происходит так много переопределений, монолит существенно изменяется. Важно помнить, что зависимость между объёмом нового функционала и количеством модулей нелинейная: для добавления одной функции нужно внести изменения в несколько модулей, каждый из которых меняет работу другого. Или в новом модуле переопределить большое количество методов других модулей, что сути не меняет.
После всех изменений система так усложняется, что для добавления следующих кастомизаций будет требоваться неприлично большое количество часов.
Проблема № 2. Принцип самодокументирования не поддерживается в модульных системах
Документацию для модульных систем сложно поддерживать в актуальном состоянии. Её много, и она устаревает с каждым изменением. Доработка одного модуля влечёт изменения в нескольких других документах (в пользовательской, технической документации),и их все нужно переписывать.
Как правило, заниматься такими работами некому: тратить время ценных IT-специалистов на это — значит просто сливать бюджет. Даже использование хранения документации в коде (PHPDOC) не гарантирует её достоверности. В конце концов, если документация может отличаться от реализации, она обязательно будет отличаться.
Проблема № 3. Большая связность кода — путь к регрессии: «здесь изменили — там отвалилось»
Классические проблемы модульных систем — в части борьбы с регрессией.
Разработку по TDD сложно использовать для монолитов из-за большой связанности разных методов (на 5 строчек кода можно запросто потратить 30 строчек тестов, плюс фикстуры). Поэтому при борьбе с регрессией приходится покрывать функционал интеграционными тестами.
Но ввиду и без того медленной разработки (ведь разрабатывать нужно аккуратно, чтобы предусмотреть много переопределений), заказчики не хотят платить за сложные интеграционные тесты.
Функциональные тесты становятся настолько большими, насколько и бессмысленными. Они выполняются часами даже в параллельном режиме.
Да, современный front вроде PWA можно тестировать API-функционально. Но тесты часто зависят от получения данных из внешнего контура — и поэтому начинают фейлится, если, например, тестовый SAP отстаёт от продуктового на N месяцев, а тестовый «1С» присылает неверные данные.
Когда же приходится выложить небольшую правку по какому-нибудь модулю, разработчики должны выбирать из двух зол: запустить полный прогон CI и потратить кучу времени на деплой, или выложить хотфиксом без прогона тестов, рискуя всё-таки что-то сломать. Весьма драматично, когда такие правки прилетают от отдела маркетинга в Чёрную Пятницу. Безусловно, рано или поздно, регрессия и человеческая ошибка случится. Знакомо?
В конечном итоге, для выполнения бизнес-целей команда переходит в авральный режим работы, умело жонглирует тестами и внимательно смотрит на дашборды из логов - Кибаны, Графаны, Заббиксы... А что получаем в конце? Перегорание.
Согласитесь, такая ситуация с регрессией не похожа на «стабильный Enterprise», каким он должен быть в мечтах и грёзах заказчика.
Проблема № 4. Связность кода и обновление платформы
Ещё одна проблема связанности кода — это сложности при обновлении платформы.
Например, Magento содержит два миллиона строк кода. У «Битрикса» тоже большое количество кода, ещё и архитектура с..м.. «уникальными особенностями». Посмотрим на специализированное решение? Ок, Akeneo 1.7 — то же самое. Когда обновляются эти монстры, нужно рефакторить весь свой проект!
Приведу пример для Magento (похожие случаи есть в любой модульной системе на крупных проектах).
В конце 2018 г. вышла новая версия платформы Magento 2.3. В Open Source Edition были добавлены мультисклады и Elasticsearch. Кроме того, в ядре были исправлены тысячи ошибок и добавлены некоторые приятности в OMS.
С чем столкнулись e-Commerce-проекты, у которых уже были написаны мультисклады на Magento 2.2? Им было нужно переписывать кучу логики в обработке заказа, чекауте, карточке товара, с тем, чтобы перейти на коробочный функционал. Ведь «так правильно» — зачем дублировать в модулях функционал коробочной версии? Уменьшить количество кастомного кода в большом проекте всегда полезно.
Теперь представьте: сколько времени уйдёт на такое обновление? Как это можно тестировать без интеграционных тестов, которые писать затруднительно?
Не удивительно, что обновление платформы у многих проходит или без рефакторинга, но с увеличением дублирования, или (если команда хочет делать всё по феншую), с «уходом» надолго в рефакторинг и наведение порядка.
Проблема № 5. Непрозрачность бизнес-процессов
Одна из самых важных проблем в управлении проектами состоит в том, что заказчик не видит всю логику и все бизнес-процессы проекта. Их можно лишь восстановить из кода или из документации (актуальность которой, как мы говорили ранее, проблематично поддерживать в модульных системах).
Да, у «Битрикса» есть BPM-часть, а у Pimcore — визуализация Workflow. Но эта попытка управлять модулями с помощью бизнес-процессов всегда вступает в противоречие с наличием ядра. Кроме того, эвенты, сложные таймеры, транзакционные операции — всего этого не может быть полноценно в системе модульной архитектуры. Ещё раз, я повторюсь, это касается средних и крупных компаний. Для небольшой компании возможностей модульных систем хватит. Но если мы говорим про enterprise-сегмент, то в этом решении весьма не хватает единого центра управления, куда можно зайти и посмотреть на схеме любой процесс, любой статус, как именно что-то происходит, какие есть исключения, таймеры, события и кроны. Не хватает возможности изменять бизнес-процессы, а не модули. Процессное управление проектом захлёбывается в скорости изменений и связанности логики.
Проблема № 6. Сложность масштабирования системы
Если вы разворачиваете монолит (например, на Magento, «Битриксе», Akeneo, Pimcore, Opencart и т.п.), то он будет развёрнут целиком со всеми модулями на каждом app-сервере.
Нужно больше памяти и процессоров, что сильно повышает стоимость кластера.
Как микросервисы избавляют заказчиков от недостатков, типичных для модульной разработки. Оркестрация микросервисов в Camunda и jBPM
Спойлер: решение перечисленных в прошлом пункте проблем возможно с использованием BPMS и оркестрированием микросервисных систем.
BPMS (англ. Business Process Management System) — это программное обеспечение для управления бизнес-процессами в компании. Популярные BPMS, с которыми работаем и мы: Camunda и jBPM.
Оркестровка описывает то, как сервисы должны взаимодействовать между собой, используя для этого обмен сообщениями, включая бизнес-логику и последовательность действий. Используя BPMS, мы не просто рисуем абстрактные схемы; по нарисованному наш бизнес-процесс и будет выполняться. То, что мы видим на схеме, гарантированно коррелирует с тем, как работает процесс, какие микросервисы используются, какие параметры и по каким таблицам решений происходит выбор той или иной логики.
За пример взят часто встречающийся процесс: «Отправка заказа в доставку».
По какому-либо сообщению или прямому вызову, мы запускаем обработку заказа с процессом выбора метода доставки. Задана логика выбора.
В итоге процессы, сервисы и разработка:
- становятся быстро читаемыми;
- самодокументируемыми (они работают именно так, как нарисованы, и нет рассинхрона между документацией и реальной работой кода);
- просто отлаживаемыми (легко посмотреть, как проходит тот или иной процесс, и понять, в чём ошибка).
Познакомимся с принципами, по которым работают системы управления бизнес-процессами.
Принцип BPMS № 1. Разработка становится визуальной и процессной
BPMS позволяет создать бизнес-процесс, в котором команда проекта (разработчик или бизнес-пользователь) определяет последовательность запуска микросервисов, а также условий и веток, по которым он движется. При этом один бизнес-процесс (последовательность действий) может включаться в другой бизнес-процесс.
Всё это наглядно представлено в BPMS: в режиме реального времени можно смотреть эти схемы, их править, выкладывать в продуктив. Принцип самодокументируемой среды тут выполняется максимально — процесс работает именно так, как это визуализировано!
Все микросервисы становятся кубиками процесса, которые можно добавлять из оснастки бизнес-пользователю. Бизнес управляет процессом, а разработчик ответственен за наличие и корректность работы конкретного микросервиса. При этом все стороны понимают общую логику и назначение процесса.
Принцип BPMS № 2. Каждый сервис имеет понятные входы и выходы
Принцип звучит очень просто, и для неопытного разработчика или бизнес-пользователя может показаться, что BPMS никак не улучшает саму стратегию написания микросервисов. Мол, и без BPMS нормальные микросервисы можно писать.
Да, можно, но сложно. Когда разработчик пишет микросервис без BPMS, у него неизбежно возникает желание сэкономить на абстрактности. Микросервисы становятся откровенно большими, а иногда и начинают переиспользовать другие. Появляется стремление сэкономить на прозрачности передачи результата от одного микросервиса к другому.
BPMS побуждает писать более абстрактно. Разработка ведётся именно процессно, с определением входа и выхода.
Принцип BPMS № 3. Параллелизация обработки очереди
Представьте процесс обработки заказов: нам нужно сходить в некий маркетплейс, забрать все хорошие заказы и начать их обрабатывать.
Посмотрите на схему (часть схемы). Тут определено, что каждые 10 минут мы проверяем все заказы маркетплейса, потом запускаем параллельно (на что указывает вертикальный “гамбургер” в Process Order) обработку каждого заказа. При успехе передаём все данные в ERP и завершаем обработку.
Если вдруг нам потребуется поднять логи по обработке конкретного заказа, в Camunda, jBoss или любой другой BPMS мы сможем восстановить полностью все данные, увидим, в какой очереди это было и с какими параметрами вход/выход.
Принцип BPMS №4. Ошибка и эскалация
Представьте, что в процессе доставки товара произошла ошибка. Например (кстати, это реальный кейс), транспортная компания забрала заказ, а склад после этого сгорел. Другая реальная история: предновогодний аврал, и товар сначала задержался, а потом, может быть, и потерялся.
В таком случае в BPMS мышкой накликивают события, например, уведомления клиента в случае, если время доставки прошло.
В случае, если от транспортной компании внутри получили какую-то ошибку, мы можем запустить процесс по своей ветке и всё прервать: уведомить, дать скидку на следующий заказ, вернуть деньги. Все подобные исключения не только сложно программировать вне BPMS (например, таймер в таймере), но и сложно понимать в контексте всего процесса.
Принцип BPMS №5. Выбор действий по одному из событий и межпроцессные варианты
Представьте всё тот же заказ в доставке.
Итого, у нас три варианта развития событий:
- товар был доставлен в ожидаемые сроки;
- товар не был доставлен в ожидаемые сроки;
- товар был потерян.
Прямо в BPMS мы можем определить процедуру отгрузки товара в транспортную компанию и ожидать по заказу одного из событий:
- успешной доставки (сообщения от процесса доставки товара о том, что всё доставлено),
- или наступления какого-то времени.
Если время не прошло, вам нужно запустить другой сервис: разбор с оператором этого конкретного заказа (ему нужно поставить задачу в OMS/CRM-систему, чтобы расследовать, где заказ), и далее уведомить клиента.
Но если в процессе расследования заказ всё-таки был доставлен, нужно будет прервать расследование и завершить обработку заказа.
В BPMS все прерывания и исключения на стороне BPMS. Вы не перегружаете код этой логикой (а само наличие такой логики в коде сделало бы микросервисы большими и плохо переиспользуемыми в других процессах).
Принцип BPMS №6. В вашей Camunda вы увидите все логи
С помощью событий и межпроцессного варианта, вы:
- видите всю последовательность событий в одном окне (что с заказом, по какой ветке исключений он прошел и т.п. — легко посмотреть);
- можете собрать всю аналитику для BI на основании одних только логов BPMS (без необходимости перегружать микросервисы логирующими событиями).
В результате, вы сможете собрать статистику именно по проблемам обработки, скорости переходов, всех процессов по компании. Появляется унифицированность логирующей информации, и легко увязать событие в доставке с действием оператора или событием любой другой информационной системы.
Обратите внимание на разницу с модульной системой. Там тоже можно сделать универсальные логи. Но при взаимодействии с другими системами нужно будет что-то делать с унификацией логирования и в них, а это далеко не всегда возможно.
Итоги сравнения микросервисной и модульной архитектуры
Каждый тип построения архитектуры имеет свои преимущества и недостатки; универсального решения нет. Для малого бизнеса или при использовании совсем небольшого количества кастомизаций, модульный подход будет более подходящим. Важно искать подходящее техническое решение, а не пропагандировать конкретную платформу или подход.
Как итог, рассмотрим, как меняются разные типы архитектуры в зависимости от срока жизни проекта.
На старте проекта:
- с микросервисами — у вас нулевой функционал, и весь его нужно написать, чтобы приступить к работе;
- с модульной системой — из коробочной версии вам доступно сразу же много функционала, и вы можете начинать пользоваться продуктом в ближайшее время после покупки.
После первых 3-4 месяцев разработки (это средний срок выпуска первого MVP) и далее:
- с микросервисами — количество функционала постепенно выравнивается по сравнению с коробочной версией. Для среднего бизнеса, микросервисная архитектура догонит модульную достаточно быстро, а для крупного — вообще мгновенно. И в дальнейшем поддержание и развитие модульной системы в пересчете на единицу функционала будет увеличиваться.
- с модульной системой — скорость развития функционала будет значительно ниже, чем в микросервисах.
В заключение давайте рассмотрим, как выглядит оркестрация микросервисов на конкретных примерах.
Примеры визуализации оркестрации сервисов
Рассмотрим оркестрацию сервисов с использованием Camunda. По следующим изображениям вы сможете оценить, как удобно управлять микросервисами с помощью BPMS с оркестратором. Все процессы наглядны, логика очевидна. Бизнес-процессы выглядят так:
Пример (заказ, сервис наличия):
Видно, что в этом заказе была ветка «Нет товара».
Другой экземпляр заказа (ушёл на сборку):
Заказ пошёл дальше и по таблице решений (DMN) ушёл в ветку обработки определённым оператором службы доставки (Boxberry):
Уход на вложенный процесс:
Вложенный процесс отработал:
История прохождения бизнес-процессов:
Свойства такой визуализации:
● бизнес-процессы легко читаются даже неподготовленным пользователем;
● они исполняемы, т.е. работают именно так, как нарисованы - нет рассинхрона между “документацией” и реальной работой кода;
● прозрачны: легко посмотреть как проходил тот или иной импорт, заказ, обработка и понять где ошибка).
Смотрите также: видео kt.team на тему «Микросервисная или монолитная архитектура: что выбрать?»