Разрушая монолиты: когда большие  автоматизированные системы пора менять на микросервисы

Решения в области дистанционного банковского обслуживания юридических лиц (ДБО ЮЛ) довольно продолжительное время строились на монолитных автоматизированных системах подрядчика. Вначале было Legacy от BSS, потом решение от R-Style SoftLab. В таких монолитах нет ничего плохого, это отличный базис, который не просто поддерживает жизнеспособность системы, но и до определенного момента оставляет простор для развития. Однако есть в них и минусы, и чем больше массив становится, тем острее они ощущаются.

dc5d4eff5a4d5e96fce24be92051dbc9.png

Если вы оказались в яме, перестаньте копать

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

источник - Yandexисточник — Yandex

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

a741f287d6d1dc8b6fea6df02e4000ba.png

Разрушить, чтобы создать

Отличный способ начать перевод монолитного приложения на микросервисную архитектуру — это для начала снизить темпы развития. Это, как ни парадоксально, ускоряет реализацию новых функций, поскольку разработка происходит в совершенно новой кодовой базе. Такой подход также позволяет быстро продемонстрировать выгоды от перехода на микросервисы — наши бизнес-подразделения сразу почувствовали уменьшение времени вывода функциональности time-to-market.

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

Так у нас стали появляться такие микросервисы, как «Депозиты», «Кредиты», «Переводы» и т.д. Осталось только заставить их взаимодействовать друг с другом.

b0b844d3ad6878c42422512ed5809007.png

События против синхронизации

По сути, есть два распространенных способа взаимодействия микросервисов: синхронный (запрос-ответ) и асинхронный (по событиям).

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

На примере банковского сервиса это выглядит так. Клиент может настроить запрос по остатку средств на счёте каждые 10 минут. При этом реальные изменения на счёте происходят значительно реже. Независимо от того, поменялось что-то в реальности или нет, сервис будет выполнять одинаковый объем операций, проверяя баланс. Клиент всё равно опрашивает сервер, а сервер обрабатывает этот запрос. При этом каждый клиент может настроить разную частоту обновлений: кто-то будет проверять баланс каждые 10 минут, кто-то — каждые 2 часа, кто-то — 1 раз в 2 недели. Так сервер становится узким местом. Клиент «блокируется» в ожидании ответа, тратятся ресурсы системы, происходит потеря производительности. Еще серьезней ситуация становится, когда все эти клиенты одновременно обращаются к серверу, или один клиент направляет множество новых запросов. В таком случае сервер может просто исчерпать свои ресурсы и «упасть». Поэтому чтобы максимально повысить уровень доступности автоматизированных систем, необходимо минимизировать синхронные взаимодействия.

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

  • работоспособность клиента-микросервиса не зависит от сбоев сервера;

  • микросервис-клиент не может «завалить» сервер;

  • микросервис-клиент не ждёт ответа, а решает дополнительные задачи, это позволяет использовать вычислительные ресурсы максимально эффективно;

  • она позволяет просто расширять систему при появлении новых потребителей информации.

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

© Habrahabr.ru