Как «Цифра» меняет инфраструктуру уже работающего приложения
Отказоустойчивость повышается за счет модульного подхода.
Немного хотел бы погрузить в суть темы, для понимания решения, которое, на мой взгляд, мы успешно нашли и применили.
Эта история началась в конце 2021 года, когда наш «духовный наставник» Мурад Шихмагомедов поставил задачу разработать модульную архитектуру в мобильном приложении «Цифра банк» с целью улучшения отказоустойчивости работы приложения. На тот момент было принято решение сделать «псевдо-модульность», поскольку истинная модульная архитектура в рамках текущего стэка инструментов казалась невозможной. В результате, разработка приложения «Цифра банк» проводилась с использованием этого подхода.
Задача была не из простых, поскольку было две серьезные проблемы: «интеграция блока навигации модуля» и механизмы отладки и разработки. Мне хотелось создать что-то самостоятельное, некую сущность, которая будет функционировать отдельно. Но как это сделать, как собрать «Вольтрона» (ностальгия из детства)?! На обдумывание задачи у меня ушло около 3 месяцев, ответ, к счастью, был найден и, как это всегда бывает, он оказался достаточно простым.
Если опустить технические части, я наделил свои модули «самостоятельностью». Идея заключалась в том, что не ядро дает инструкции действий, как это обычно принято, а модуль определяет поведение ядра. Этот подход стал фундаментом для реализации данного решения.
Это могло бы так и остаться лишь идеей, а идеи, как мы знаем, редко находят дальнейший свой жизненный путь, если бы не мой коллега Ярослав Белецкий. Он не только смог реализовать задумку, но и приумножить ее возможности.
Первый модуль уже внедрен в релиз, эта архитектура вовремя подошла к нашим внутренним банковским процессам по Agile-трансформированию. Теперь мы можем эффективно разделять разработку не только на продуктовые команды, но изолировать их на уровне модулей.
P.S. Более подробно об этом расскажет Ярослав
От идеи к реализации
Когда задача поступила в мой адрес, я стал думать, как ее реализовать правильно и более масштабированно. Framework, на котором мы пишем мобильное приложение, является React Native. Выбран он был неспроста: его главным преимуществом является кроссплатформенная разработка, параллельное создание продукта одновременно для двух платформ – iOS и Android. При этом, по своей сути React Native не предполагает создание модульной архитектуры, у него есть библиотеки – это набор неких готовых решений для определенного функционала. Чтобы не вникать в код, можно взять решение из библиотеки, посмотреть зависимости, документацию и использовать. Такие библиотеки реализуют такой функционал как к примеру управление push-уведомлениями, геолокацией, оплата картой, навигация в приложениях.
Исходя из моего опыта создания подобных библиотек, у меня появилась мысль создать что-то похожее для нашей команды, на основе пакетов-зависимостей, которые будут браться из одного места, а использоваться в сразу в разных продуктах. Располагаться они будут каждый в своем репозитории, тем самым можно избежать внутренних конфликтов, пересекающихся процессов и добиться независимой разработки процессов.
Грубо говоря, есть один склад, на котором находятся все ресурсы - уже готовые шаблоны бизнес-процессов. И эти шаблоны можно использовать в любом другом мобильном приложении, которое написано с помощью framework React Native.
В нашем случае приложение – это ядро, та сущность, которая хранит в себе контекст. Модули – это отдельные бизнес-процессы, такие как авторизация, переводы, чат, кредиты, карты, счета. Мы разбили наше банковское приложение на эти части и разнесли в разные модули. В итоге каждый разработчик получил возможность работать в своем репозитории, не мешая другим.
Для того, чтобы собирать приложения для публикации в маркеты, нам нужен был инструмент. Я также дополнительно разработал этот функционал. Требования к инструменту, которые передо мной стояли:
→ Сборка ядра с выбором необходимых модулей. Можно собрать приложение только, допустим, с модулями авторизации, переводами и чатом, минуя другие.
→ Возможность запускать процессы параллельно. То есть команды могут собрать каждый свое мобильное приложение со своими модулями для dev-тестирования.
→ Возможность совершить несколько сборок. Приложение собирается один раз, но сразу на три контура – dev-тестирование, test (на котором проводится регресс-тестирование) и production.
Было еще одно небольшое дополнительное требование – разграничение доступа к функционалу для разработчиков и тестировщиков.
Сборка
Так как у нас кроссплатформенная разработка, нам необходимо собирать сразу две платформы. Для Android мы можем собрать как на операционной системе Windows, так и на macOS, а iOS собирается только на macOS. Поэтому наш ресурс должен был лежать на сервере, который имеет операционную систему macOS. Мной был написан backend-сервер, который обрабатывает все запросы и умеет делать сборки, был написан web-интерфейс с различным функционалом.
Все модули лежат на GitLab Self-hosted. Я публикую бизнес-модули внутри каждого репозитория отдельно. Сборщик заходит в репозитарий на GitLab, смотрит на зависимости, которые имеет ядро, и собирает пакет.
Внутри ядра также есть конфигурационный файл по управлению ресурсами, чтобы сборщик видел где и что брать. После сборки приложений для Android и iOS, они публикуются в стандартные среды тестирования для каждой платформы.
Каждый модуль представляет из себя обычный npm-пакет. Ядро практически ничего не знает о том, что находится в каждом модуле. Оно только знает, что есть такой-то пакет, где его брать и как его внутри устанавливать. Чтобы ядро увидело модуль, его нужно подключить к нему, поэтому каждый модуль декларирует, как его устанавливать, а ядро содержит информацию о необходимых ему модулях.
Всем остальным управляет сам модуль. У него свой сетевой клиент, своя бизнес-логика, навигация. То есть это отдельная монолитная сущность, а ядро – это хранитель контекста, куда подключаются все модули. Первая версия модуля появилась в конце декабря. Первый раз, когда архитектура видела свет production, – середина января, это был модуль авторизации. Сейчас мы переписываем все мобильное приложение по модулям, работа сделана уже на 80%. Как только мы перенесем всю оставшуюся часть, то сможем использовать уже написанный нами сборщик.
Что это даст?
Какой будет результат:
✔ Не надо будет ждать выпуска релиза другого модуля.
✔ Независимая разработка. Нет никаких конфликтов между разработками.
✔ Обеспечение большей независимости от сторонних сервисов. Если в какой-то момент сторонний сервис не сможет с нами сотрудничать, то мы можем оперативно отключить модуль, в котором он участвует, и работать над его изменением, а не проводить обновление и длительную вычитку всего мобильного приложения в поисках зависимостей от этого сервиса.
✔ И, конечно же, повышение уровня отказоустойчивости мобильного приложения.
На пике производство приносило около 500 000 ₽ прибыли в месяц на двоих, но в 2024 я закрылся с убытком в 6,5 млн ₽.
Пользователи дуреют с этих приколов. Но вы так ни в коем случае не делайте.
Привет. Вы меня никогда раньше не видели. Как и один миллион человек, которые регулярно смотрят видео на Простой экономике – канале, который я начал вести пять лет назад. Эти пять лет я жил две жизни.
Я месяц бегал на беговой дорожке и месяц я занимался на улице, чтобы понять, где всё таки сжигается больше жира. Результаты меня удивили... так вот я о чём...
В России вводятся новые нормы, ужесточающие ответственность за утечку персональных данных. Рассказываем что изменится, какие штрафы грозят, и что делать, чтобы не получить письма счастья.
Врачебный кабинет и консультации в рамках одного Telegram-бота. В статье расскажем о непростом клиентском запросе, разработанном решении и немного о планах на будущее.
Заказать сайт — задача, которая требует не только финансовых вложений, но и четкого понимания ваших целей. Чтобы процесс разработки прошел гладко, а результат оправдал ожидания, важно сразу предоставить исполнителю всю необходимую информацию. Вот что нужно учесть, чтобы сэкономить время, нервы и бюджет.
О чем они вообще пишут? Ваше приложение самое глючное из всех банковских приложений что я видел, на андроид периодически зависает на входе по отпечатку, на ios глюк с тем что в брокерский счет для перевода не набираются буквы (на андроид набираются)
Пользуюсь только от безысходности тк нужны переводы в FFIN KZ
Если отзывы в сторе почитать можно вообще охренеть от обилия таких глюков
В React Native ничего из этого вообще нет? Мне казалось что мультимодульная структура, build types и build flavors это основы
"основы" чего?
У каждого проекта свои требования, назначение и цели.
И build types/flavours далеко не всем нужны.
Сами выдумали проблема и сами же закостылили. При чем абсолютно непонятно как это решает вопрос отказоустойчивости - если у вас что-то на фронте не работает, то и в npm модуле не будет работать и в стандартном компоненте.