2023/12/11 12:32:53

Как создать эффективный маркетплейс финансовых услуг: рекомендации для крупных игроков рынка

Директор дивизиона технологического развития клиентских организаций Группы «Иннотех» (Холдинг Т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.

Планы по развитию маркетплейса

В ближайшие месяцы наша команда сфокусируется на четырех основных аспектах:

  1. Расширение функциональности сервиса. Исходное решение было «заточено» под легковые автомобили. Сейчас наша команда работает над тем, чтобы маркетплейс поддерживал разные сегменты транспорта: грузовой, спецтехнику, сложные сделки, такси и так далее.
  2. Редизайн приложения. Изначально дизайн сервиса был «техническим» — в режиме MVP. В настоящий момент мы занимаемся его переделкой и создаем современный user-friendly интерфейс в приложении.
  3. Учет негативных сценариев. Маркетплейс, над которым мы начали работать, изначально предполагал, что пользователь сразу поймет, как пользоваться сервисом, а также будет знать, какой автомобиль хочет приобрести. То есть его разработчики не допускали отрицательный опыт. Сейчас мы стараемся учитывать в том числе негативные сценарии и стремимся сделать любой пользовательский опыт позитивным.
  4. Информационная безопасность на всем конвейере разработки — от статического анализа кода до пентеста (тесты на преодоление защиты). Раньше практики ИБ применялись фрагментарно и в ручном режиме. Сейчас мы планируем внедрять их непосредственно в конвейер: с одной стороны, это поможет автоматизировать их применение, с другой — гарантирует, что ни один релиз не будет выпущен в промышленную эксплуатацию при наличии потенциальных уязвимостей.