Корпоративное ПО, Финтех
Java (Spring)
Клиент — разработчик IT-решений для банков и финансовых организаций. В составе объединённых проектных команд работает с крупнейшими банками России. Один из таких проектов — масштабная трансформация клиентских цифровых сервисов для крупного федерального банка.
На момент старта проекта основная система заказчика представляла собой монолитные Java-приложения для обслуживания физических и юридических лиц. Монолит включал десятки взаимозависимых модулей, почти весь бизнес-процесс работал в рамках одного приложения.
Проблемы:
1. Сложность сопровождения и масштабирования. Любое изменение требовало пересборки и развёртывания всего монолита. Это увеличивало время на тестирование и затрудняло развитие отдельных функций. С ростом нагрузки производительность снижалась, особенно в периоды пиковых обращений клиентов.
2. Низкая отказоустойчивость. Монолит не позволял локализовать сбои. Ошибка в одном модуле могла вывести из строя весь клиентский контур, включая мобильное приложение и веб.
3. Долгий релизный цикл. Обновления выходили раз в 4-5 недель. Все изменения поставлялись единым пакетом, что усложняло тестирование и повышало риски при выкатке. Быстрое реагирование на фидбек было невозможно.
4. Отсутствие гибкости в выводе функциональности. Новые функции было трудозатратно включать для отдельных сегментов пользователей. A/B-тесты, гипотезы и поэтапные релизы — технически реализуемы, но крайне затратны.
Чтобы ускорить выпуск новых функций, повысить отказоустойчивость и масштабируемость, было принято решение перейти на микросервисную архитектуру с полной перестройкой backend-сервиса под современные требования.
Задачи:
Сложность проекта усилилась тем, что часть функциональности была критичной и высоконагруженной: авторизация, история транзакций, работа со вкладами и платежами, витрина продуктов, СБП. Перенос требовал не просто переписывания кода, а проектирования архитектуры заново.
Мы решили эту задачу, синхронизируясь с архитекторами заказчика и проектируя микросервисную модель поэтапно — с плавным выводом функциональности на прод и стабильной поддержкой существующих клиентов. Все новые сервисы создавались с нуля — по возможности изолированно от монолита, по согласованным архитектурным схемам.
Совместно с архитекторами заказчика мы определяли, какие части старой системы можно безопасно вынести, чтобы не перегружать уязвимый монолит. Для каждого микросервиса на входе мы получали описание архитектуры, ожидаемую бизнес-логику и требования к взаимодействию с внешними системами. На выходе — наша команда брала на себя полный цикл: проектирование, реализация, подготовка профилей нагрузочного тестирования и обслуживание дефектов.
Функциональность, которая была вынесена в отдельные сервисы:
Параллельно с разработкой микросервисов разработчики обучали мобильное приложение получать данные не из монолита, а из новых точек входа.
Алексей, техлид бэкенда: «Изначально у нас была классическая монолитная Java-система с несколькими высоконагруженными микросервисами, которые решали отдельные задачи, например, обработку кредитных заявок или рекламных кампаний. Вся основная бизнес-логика была связана с Oracle — привычной для банков СУБД, но со своими сложностями в масштабировании и миграциях. Переход на микросервисы с Kubernetes позволил нам разбить монолит на независимые части, что значительно повысило устойчивость системы. Мы внедрили AppFarm для удобного управления тестовыми и продакшен окружениями, что автоматизировало процессы и ускорило релизы. Переход с Oracle на PostgreSQL для новых сервисов связан с более гибким управлением данными и возможностью использовать современные инструменты, такие как jOOQ для типобезопасных SQL-запросов и Liquibase для удобного контроля версий и миграций базы данных. Параллельно мы начали переносить фронтенд на React — это облегчает поддержку и развитие пользовательских интерфейсов, позволяя быстрее внедрять новые функции.» |
---|
Совместно с банком внедрили нагрузочное тестирование, максимально приближенное к прод-среде. Проверяли устойчивость системы при пиковом потоке (до 6 млн пользователей). Возникшие проблемы оперативно устранялись на уровне архитектуры и реализации микросервисов.
Отдельный микросервис отвечает за то, какая функциональность доступна конкретному клиенту. Новый подход позволил включать фичи выборочно — например, только для сотрудников или ограниченной группы клиентов. Это снижает риски: если гипотеза не подтверждается, функциональность можно быстро отключить.
Ранее подобное было технически возможно, но ресурсоёмко — каждый релиз приходилось собирать и выкатывать целиком.
Благодаря этому появилась возможность выпускать новые функции поэтапно:
Реальный кейс: банк решил скрыть часть неактивных продуктов клиента и показывать на главном экране только избранные. На монолите это изменение сразу попало ко всем пользователям, вызвав массовые обращения в поддержку. В новой архитектуре такой функционал можно выкатывать постепенно и безопасно откатывать в случае негатива. |
---|
Переход на CI/CD (непрерывную интеграцию и непрерывное развертывание) существенно изменил процесс выпуска новых версий системы. Раньше обновления требовали ручного вмешательства: администраторы или инженеры должны были вручную загружать и настраивать код на серверах, что занимало много времени и создавало риск ошибок.
Теперь все этапы — от интеграции нового кода, его автоматического тестирования до развертывания на разных окружениях — выполняются автоматически. Это значит, что после того, как разработчики загрузили изменения, система сама собирает сборку, прогоняет тесты и выкатывает её на несколько тестовых контуров (в нашем случае их четыре).
Там, где не удавалось сразу отказаться от старого монолита, использовался входной сервис на базе NGINX. Он определял, к какому окружению направлять запрос: если мобильное приложение старого формата — в монолит; если новое — в микросервисы.
Было (монолит) | Стало (микросервисы) |
---|---|
Вся логика — в одном коде: авторизация, заявки, транзакции, реклама, СБП и т.д. | Каждая функция — отдельный микросервис: изолирована, масштабируема, проще поддерживать |
Релиз раз в 3–4 недели, вручную, с остановкой системы | Релизы каждые 1–2 недели, полуавтоматически, без простоя |
Обновление клиента требовало изменений в монолите | Новый клиент работает напрямую с нужными микросервисами |
A/B-тесты и выборочный релиз — затратны и рискованны | Возможность включать фичи поэтапно для отдельных групп пользователей |
Изменения невозможно быстро откатить | Любой микросервис можно отключить без воздействия на остальную систему |
Один сбой — падение всей системы | Сбой в одном сервисе не влияет на другие |
Тестирование производительности — точечное | Выделенная команда, полноценное нагрузочное тестирование под 6 млн пользователей |
Неудобное масштабирование: весь монолит под нагрузкой | Горизонтальное масштабирование нужных сервисов под пиковую нагрузку |
Всё API завязано на один backend | Каждое клиентское приложение общается с нужным набором сервисов |
Невозможно обновлять фронт отдельно от backend | Фронт может меняться независимо, без жёсткой синхронизации с core |
Технологии до перехода:
JetBrains IntelliJ IDEA, Oracle SQL Developer, Fiddler, Postman, Java SE, PostgreSQL, Oracle Database, React, Redux
Технологии после перехода:
Java 17+, String Boot, liquibase, Kafka, PostgreSQL, docker, CI/DI, GitLab, React