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

Я Максим Сухов,  руковожу дивизионом технологического развития среднего и малого бизнеса в Иннотех,  основного ИТ-партнёра ВТБ. А раньше был  заместителем начальника управления и ИТ-лидером стрима «Мобильный банк для бизнеса» в ВТБ. Расскажу,  как команда стрима «Мобильный банк для бизнеса» переходила с Legacy-монолита на микросервисную архитектуру новой омниканальной платформы, какие требования предъявляла к новому инструменту и что получила с выбором Tarantool.  

Статья написана по итогам совместного вебинара с Дмитрием Слипцом, архитектором стрима «Мобильный банк для бизнеса» (ВТБ), и Максимом Суховым, ИТ-лидером стрима: «В погоне за комфортом: как улучшить пользовательский опыт с использованием архитектуры микросервисов». 

Отправная точка: Legacy-монолит


«Мобильный банк для бизнеса» — один из ключевых каналов взаимодействия банка ВТБ с клиентами. Система тесно интегрирована в общий ИТ-ландшафт компании и развивается в соответствии с общей стратегией.

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



Наш мобильный банк состоит не только из мобильного приложения, но и из Middleware-слоя. В нашем кейсе он отвечает за кэш и часть функций, которые не предоставляют мастер-системы. Middleware-слой содержит минимум логики работы с данными, он ориентирован только на получение запросов и передачу информации. До ИТ-трансформации наш Middleware-слой взаимодействовал с Legacy-монолитом. В рамках трансформации этот монолит нужно было заменить набором систем с мастер-данными, из которых предстояло собрать, как пазл, экраны нашего приложения. Для этого нам требовалась универсальная система управления данными, способная справляться с большим количеством запросов. При этом нужно было учитывать несколько важных факторов:

  • глобальность изменений. Мастер-системы создавались параллельно с нами, менялись спецификации, форматы и состав данных. Многие внутренние инструменты выходили с MVP, и не все были готовы гарантировать нужный нам RPS с первого дня. Таким образом, при пересмотре архитектуры мы должны были закладывать значительный запас на стабилизацию и дальнейшее развитие систем, с которыми мы интегрированы;
  • недопустимость сбоев. Одно из основных требований — для клиентов переход на новое решение должен пройти незаметно и бесшовно. Потеря данных, их некорректное отображение или даже краткосрочная недоступность приложения недопустимы;
  • потенциальное увеличение клиентской базы. Мы ожидали рост клиентской нагрузки, которая также могла линейно повлиять на наших соседей, мастер-системы, инфраструктуру банка. Надо было найти решение, которое может масштабироваться независимо.

Выбор инструмента: обстоятельства и ограничения


Мы не изобретали велосипед, но работа в контуре Enterprise-системы накладывает ряд ограничений на свободу выбора инструмента для перехода с монолита на микросервисы:

  1. Решения банка должны состоять из утвержденного набора компонентов. Не должно быть «зоопарка технологий».
  2. Мобильный банк для СМБ — Mission-critical-система, которая является витриной для продуктов, предоставляемых клиентам. Поэтому инструмент должен обеспечивать Latency ≤ 1 сек (на все каскадные вызовы), RPO ~ 0>, RTO ~ 0, доступность — 99,99% независимо от количества вызовов в Middleware-слое.
  3. Инструмент должен соответствовать жестким корпоративным требованиям банка по ряду технических и эксплуатационных параметров, в том числе по надежности, отказоустойчивости, масштабируемости, поддержке, компетенции внутри команды.

С технической стороны к инструменту было несколько требований:

  1. Важно бесступенчатое горизонтальное масштабирование для учета роста нагрузки и персистентность, которая гарантирует быстрое восстановление данных даже в случае сбоев на уровне сервера с кэшем. 
  2. Необходимо наличие легкой аналитики (SUM, COUNT), фактически функция агрегации. Мы не стремились переложить логику на базу данных, но выборку и фильтрацию данных рациональнее выполнять на стороне БД, а не выносить в прикладную часть приложения. К тому же это не только сокращает длительность операций, но и уменьшает риски ошибок и сбоев на каждом из промежуточных этапов.
  3. Параметры инструмента должны позволить поддерживать наши SLA (избежать долгого времени ответа от мастер-систем) и снизить нагрузку на смежные системы. Было важно, чтобы даже в случае недоступности мастер-систем можно было продолжать работу.

Одновременно с этим мы понимали, что:

  • нам не надо создавать и хранить свои объекты, данные приходят из других систем, их нужно только сохранить и быстро отобразить;
  • нам не нужны сложные выборки, необходимы запросы по ключам, а не масса JOIN’ов.

С учетом всех вводных под наш стек мы рассматривали четыре инструмента: Redis, Memcached, Apache Cassandra и Tarantool. Redis и Memcached не подошли из-за отсутствия необходимых функций, например агрегационных и аналитических. Apache Cassandra не удовлетворял наши запросы по удобству поддержки продукта и скорости реагирования на запросы со стороны вендора. В итоге в качестве хранилища данных для бэкенда новой микросервисной архитектуры мы выбрали Tarantool.



Тестирование Tarantool


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

При тестировании мы учитываем два момента:

  1. Алгоритм взаимодействия Middleware-слоя нашего приложения с Tarantool. Оно организовано через набор REST. Соответственно, бутылочным горлышком в таком порядке обмена данными являются каналы, отвечающие за передачу запросов на чтение и запись. В качестве тестовой нагрузки мы отталкиваемся от пиковых значений запросов к проду, увеличивая их на величину потенциального роста нагрузки и закладывая минимум двукратный запас.
  2. Паттерны использования «Мобильного банка для бизнеса». Функции приложения используют по-разному — запросы к каждому из них неравномерны. Например, пользователи чаще проверяют остаток на счете, чем изучают историю операций. Соответственно, нагрузка на первый сервис кратно выше, чем на второй. Мы отслеживаем паттерны взаимодействия и на основе полученных результатов знаем, какие компоненты архитектуры нужно проверять более тщательно и требовательно.

Выстраивая тестирование комплексно, мы смогли убедиться, что проблем с Tarantool не возникнет ни при передаче запросов, ни при работе с данными в кластере.  

Внедрение: едим слона по частям


У нас было два мобильных приложения — в AppStore и Google Play. Их интерфейсы, набор реализованных функций и наполнение были идентичны, поэтому перестройку мы выполняли по единому сценарию.

Динамика количества запросов к приложениям в течение дня нелинейна — ими пользуются тысячи клиентов из разных регионов, поэтому у нас нет даже незначительного интервала, когда можно допустить Downtime системы. То есть важно было вносить все изменения и переходить на Tarantool на лету. 

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



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

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

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

Сейчас в кластере, на котором развернут прод, Tarantool выдерживает до 15 000 запросов на чтение и до 8000 на запись одновременно, что полностью покрывает потребности нашего приложения. 

Может быть полезно: что мы вынесли из своего кейса


  • Переход на новую архитектуру — всегда вызов, независимо от предпосылок внесения изменений. И к нему нужно быть готовым. Всем, даже малейшим, обновлениям на уровне архитектуры должны предшествовать анализ и планирование (как краткосрочное, так и долгосрочное). Без этого можно скатиться в хаос и уже после первой итерации изменений перестать понимать, что и как должно получиться. 
  • Чем сложнее система, тем скрупулезнее нужно относиться к процессу. Критически важно не допустить в процессе изменения схемы работы и выбирать инструмент с учетом всех ограничений и требований. В нашем случае требования к решению были очень жесткие, но Tarantool выполнил их.
  • Включение нового инструмента в архитектуру и новую схему работу без предварительного тестирования на реальных нагрузках — хождение по лезвию ножа, которое может печально закончиться в любой момент. Причем тестировать нужно не только новый компонент, но и коммуникацию с ним: зачастую она тоже становится бутылочным горлышком во всей схеме. 
  • Не стоит пытаться сделать все и сразу. Задачи лучше декомпозировать, так их легче выполнять, контролировать и отслеживать результат. Подход с дроблением задачи также упрощает откат событий, если что-то пойдет не так.

Комментарии (0)