Как создать эффективный маркетплейс финансовых услуг: рекомендации для крупных игроков рынка
Директор дивизиона технологического развития клиентских организаций Группы «Иннотех» (Холдинг Т1) Константин Абакумов — о том, как за полгода довести маркетплейс до промышленной эксплуатации, и как обеспечивается производительность высоконагруженной платформы для одного из лидеров финансовой индустрии.
Содержание |
Аудит и запуск проекта
В предыдущем материале мы начали рассказывать про один из интереснейших проектов Группы «Иннотех» — внедрение маркетплейса для крупной российской финансовой компании. Наша команда «подхватила» существующий проект другого вендора и провела аудит платформы: проанализировала ИТ-архитектуру, качество кода, документацию, подходы к CI/CD и информационную безопасность. Мы отметили для себя несколько моментов:
- платформа имеет современный стек технологий, но при этом у неё есть устаревшие элементы, структура организации кода сложная, а языков программирования и фреймворков слишком много;
- необходимо отказаться от части самописных решений из-за отсутствия поддержки и заменить их на готовые решения;
- значительная часть бизнес-логики продукта реализована в монолитном BPM-решении Camunda: после приемки потребуется глубокий анализ задач на проекте и даже потенциальный пересмотр этой архитектуры;
- необходимо провести нагрузочное тестирование и полный аудит информационной безопасности для выявления потенциальных уязвимостей.
Напомню, что за шесть месяцев мы доработали и внедрили маркетплейс. В этом материале мы объясним, как нам это удалось. В частности, погрузимся в детали бэкенда и фронтенда, расскажем, как проходила сборка проекта, а также поделимся планами по развитию сервиса. |
Работа с кодом и приложением
Бэкенд. В основе платформы — микросервисы. Два из них – API Gateway для создания, публикации, обслуживания, мониторинга и обеспечения безопасности API, а также ядро сервисной бизнес-логики с BPM-движком Camunda — выполнены на Java. С помощью этого же решения реализована интеграция с базой данных.
Компания планировала внедрять распределенное и отказоустойчивое приложение, поэтому сервисы имеют stateless-архитектуру. Это значит, что каждый запрос обрабатывается независимо и не требует хранить состояние, что обеспечивает лучшую масштабируемость. Также такой подход упрощает разработку и тестирование, обеспечивает более высокую отказоустойчивость, так как отказ в одном компоненте не повлияет на остальные. Несмотря на то, что сервисы реализованы на стеке Java 11, они имели разные версии сборок виртуальных машин для развертывания приложений.
Аудит, о котором рассказывали ранее, выявил наличие риска развития ядра системы в монолит. Это чревато ненужными для бизнеса сложностями. Например, с развитием ИТ-продукта большая и разветвленная структура сервиса будет итеративно усложняться, что приводит к сильной взаимозависимости процессов, росту ошибок, отладкам и долгому тестированию при реализации новой функциональности. Поэтому мы глубоко изучили структуру платформы и разграничили бизнес-логику потребителей на отдельные сервисы. Их мы, кстати, реализовали на фреймворке Spring Boot, который позволяет создавать приложения с минимальным количеством настроек.
Также унифицировали процессы разработки и зафиксировали единую версию виртуальных машин Java (JVM) для микросервисов и сборочного конвейера. Сейчас в каждом сервисе свой набор, что позволяет быстрее выпускать новые функции в продуктив. Кроме того, пересмотрели необходимость использования в сервисах скриптов на Groovy, у которого нет предварительной компиляции, а риски ошибок в Runtime крайне высоки.
Еще один серьезный риск был на стороне API Gateway. Сервис опирался на самописную, непубличную и уже неподдерживаемую библиотеку маппинга данных от другого вендора. Мы решили отказаться от такого решения, чтобы во время валидации данных в запросах между front-end и back-end не было задержек и уменьшения производительности при работе c базой данных.
Фронтенд. Что касается фронтенда, аудит показал, что критичных проблем здесь нет. Единственное — для джуниоров и мидл-разработчиков сложность проекта очень высокая: для их «вхождения» в проект нужен руководитель, который знаком с монорепозиториями, GraphQL (язык запросов, который позволяет получать данные из API в нужном формате) и библиотекой Effector для создания эффективных и масштабируемых приложений. Наша задача заключалась в унификации работы с данными из API для участников проекта разного уровня.
В разработке веб-приложений мы решили придерживаться подхода микрофронтендеров, который предполагает разделение интерфейса на множество маленьких компонентов. Каждый компонент разрабатывается отдельно, что позволяет быстрее создавать и обновлять функциональность, улучшать качество кода отдельных частей сервиса. Такой подход отличается от традиционных – в которых все компоненты системы развертываются вместе. Однако использование микрофронтендов может привести к некоторым сложностям, таким как дополнительная координация работы между командами, необходимость в инструментах для управления зависимостями между компонентами. Все это мы предусмотрели заранее.
API. Одной из наших ключевых задач было сделать процесс получения и обновления данных более предсказуемым и управляемым. Для этого необходимо грамотное управление состоянием в приложениях, которые получают информацию из API.
Для получения данных из API в нужном формате мы использовали GraphQL, для отправки запросов и получения ответов от сервера — REST (при помощи библиотеки axios). Управляли состоянием в приложениях с помощью инструмента Effector.
Данный подход достаточно популярен, но важно иметь в виду некоторые риски.
1. Из-за одновременного использования GraphQL и REST нарушалось единообразие кода в микроприложениях. Как следствие — усложнение поддержки и развития платформы. В моменте это не приносит сложностей, но в перспективе может стать проблемой.
2. Использование Effector оправдано, хотя само решение неоднозначное. У платформы достаточно сложное API, которое повышает порог «входа» новых разработчиков. В частности, один из самых сложных блоков связан с фильтрацией — требуется несколько недель для проработки ее логики.
Хранение и сборка кода
Одна из сложностей, с которыми мы столкнулись, — монорепозиторий. Мы полностью переработали архитектуру и ушли от монорепозиториев к правильной микросервисной архиктектуре, которая синхронно отражена в репозитории, где хранится код. |
Сборка проекта. В проекте команда задействовала максимально широкий арсенал инструментов, который позволяет работать со всеми типами файлов. Дополнительно мы усилили нашу команду DevOps-инженерами с компетенциями по созданию масштабируемых и надежных серверных приложений на JavaScript и глубокими знаниями фреймворков (например, Next.js).
Смена подхода к построению веб-приложений в сторону серверного рендеринга (SSR, т.е. страница отображается на сервере, а не на клиенте, как это делает большинство современных веб-приложений) имеет много преимуществ. Мы выбрали такую стратегию, чтобы значительно сократить время загрузки страниц маркетплейса, улучшить производительность и безопасность платформы. Также было важно обеспечить возможность создания приложений, которые работают на разных платформах и устройствах. Однако использование SSR также может привести к увеличению нагрузки на сервер и времени генерации страницы – это требует дополнительных мощностей, объем которых важно прогнозировать заранее.
Для сборки проекта мы использовали веб-фреймворк Next.js — одно из лучших решений при работе на ReactJS — и технологию Server Side Rendering (SSR) для лучшей скорости загрузки страниц.
Подходы к СI/CD. Для автоматизации сборки кода, его тестирования и развертывания на сервере финансовая компания использовала платформы Docker и GitlabCI. Эти инструменты применяются для упрощения процесса разработки, улучшения качества и надежности приложений. Но был нюанс: даже при точечном изменении в одном из субприложений цикл сборки происходил для остальных сервисов. Чтобы ускорить доставку, мы разделили деплой (загрузку кода на сервер, настройку конфигурации и запуск) субприложений. Задача достаточно нетривиальная, поскольку необходимо убедиться, что все компоненты работают вместе правильно, а изменения, внесенные в один компонент, не влияют на другие.
Мы использовали: GitLab CI, Docker, Nexus, Gradle, Kubernetes, Helm.
Планы по развитию маркетплейса
В ближайшие месяцы наша команда сфокусируется на четырех основных аспектах:
- Расширение функциональности сервиса. Исходное решение было «заточено» под легковые автомобили. Сейчас наша команда работает над тем, чтобы маркетплейс поддерживал разные сегменты транспорта: грузовой, спецтехнику, сложные сделки, такси и так далее.
- Редизайн приложения. Изначально дизайн сервиса был «техническим» — в режиме MVP. В настоящий момент мы занимаемся его переделкой и создаем современный user-friendly интерфейс в приложении.
- Учет негативных сценариев. Маркетплейс, над которым мы начали работать, изначально предполагал, что пользователь сразу поймет, как пользоваться сервисом, а также будет знать, какой автомобиль хочет приобрести. То есть его разработчики не допускали отрицательный опыт. Сейчас мы стараемся учитывать в том числе негативные сценарии и стремимся сделать любой пользовательский опыт позитивным.
- Информационная безопасность на всем конвейере разработки — от статического анализа кода до пентеста (тесты на преодоление защиты). Раньше практики ИБ применялись фрагментарно и в ручном режиме. Сейчас мы планируем внедрять их непосредственно в конвейер: с одной стороны, это поможет автоматизировать их применение, с другой — гарантирует, что ни один релиз не будет выпущен в промышленную эксплуатацию при наличии потенциальных уязвимостей.