- PVSM.RU - https://www.pvsm.ru -
Как устроен современный банк? Есть бэк-офис, где выполняются разные операции, ведутся счета и отчетность. Есть мидл-офис, где принимаются решения и оцениваются риски, где оценивают кредитные риски и противодействуют мошенникам. И есть фронт-офис, где обслуживают клиентов и отвечают за их взаимодействие с банком через разные каналы.
В Сбербанке работают сотни систем разной доступности и надежности. Здесь есть и свои разработки, и коробочные решения с разной степенью кастомизации, разными SLA. Все системы интегрированы друг с другом огромным количеством способов. В этом посте мы расскажем, как весь этот муравейник фронтенда собирается таким образом чтобы обеспечивать непрерывное обслуживание клиентов.
Начнем с теории. Ключевые принципы, по которым строится отказоустойчивая система, можно позаимствовать у подводной лодки:
Проиллюстрируем первый принцип примером из своей практики. Была у нас система с распределенным кэшем. И однажды под нагрузкой один из узлов данных кэша отказал. Ничего страшного: для соблюдения нужной репликации контроллер перераспределил данные на оставшиеся узлы. Но в результате перераспределения подскочил сетевой трафик и начали теряться пакеты — в том числе служебного трафика кэша. В один прекрасный момент контроллер решил, что отказала еще одна нода с данными, вновь перераспределил данные, трафик увеличился… В итоге, менее чем через минуту система легла целиком. К счастью, дело было на нагрузочном контуре и никто не пострадал. Но на поиск причины мы потратили немало времени.
Можно возразить, что с кластеризованными базами данных и high-end серверами такое не случается — там избыточность встроена на аппаратном уровне. Процитируем Вернера Вогельса, CTO Amazon: «Everything fails all the time». Падали у нас и кластеры БД, и high-end сервера. Падали из-за ошибок конфигурации, из-за проблем в управляющем ПО. С решением каждой проблемы наше доверие к такого рода решениям снижалось. В итоге мы пришли к выводу: не отказывают только те системы, которые разделены на независимые друг от друга части — в первую очередь, независимые по управлению.
Решением проблем для нас стала многоблочная архитектура. В ней все аппаратные компоненты, включая базы данных, разделены на слабо связанные, практически независимые блоки. Каждый блок обслуживает часть клиентов, как при шардировании в базах данных. Узлы внутри каждого блока зарезервированы на всех уровнях, включая гео-резервирование. Любая проблема в одном блоке не влияет на другие. При увеличении числа клиентов мы можем легко добавить новые блоки и нормально работать дальше.
Общая архитектура блока. Все блоки зарезервированы по схеме 2N. В каждом ЦОД имеется производительный балансировщик аппаратной нагрузки. Дата-центры соединены 2-3 независимыми каналами связи.
Сервера распределены по блокам пяти типов:
Внутри каждого блока сервера приложений и веб-сервера разделены по каналам обслуживания, но базы данных при этом общие. Так мы можем изолировать наиболее распространенные сценарии отказа, чтобы они не выходили за пределы своего канала.
Сначала пользователь попадает в блок маршрутизатора. Этот блок проверяет, к какому клиентскому блоку относится человек, и отправляет его туда (или в гостевой блок). Дальше человек спокойно работает внутри своего блока. Если в родном блоке происходит отказ, человек возвращается к маршрутизатору и автоматически получает направление в резервный блок для дальнейшей работы.
Что происходит с данными во время работы? Информация о взаимодействии клиента с банком непрерывно реплицируется из клиентских блоков в архивную базу данных. Встретив пользователя, резервный блок подтягивает нужную информацию о нем из архивной базы и при необходимости выдает данные — так пользователь не подвисает при возникновении проблем с нашей стороны.
Операции, которые ведутся в резервном блоке, сохраняются в нем же. Когда родной клиентский блок пользователя восстанавливается, он переходит обратно. Операции, накопленные в резервном блоке, асинхронно переносятся в нужные клиентские блоки. Пока данные приводятся к консистентности, клиент видит сообщение о том, что все операции были приняты и сохранены, но из-за технических работ последние операции могут не отображаться.
Общая схема работы системы
В некоторых случаях переключение в резервный блок планируется заранее — например, при обновлениях в клиентском блоке. Тогда резервный блок не подхватывает сессии клиентского, а в определенный момент просто начинает все новые операции вместо него. Если необходимо экстренно переключиться на резервный блок, администратор может инвалидировать все сессии. При этом сессия пользователя прервется, и он начнет новую на резервном блоке. У блока маршрутизатора, кстати, есть свой выделенный резервный блок. Так что без запаски не остается никто.
Новые версии ПО развертываем сначала на пилотном блоке и демонстрируются ограниченной аудитории. Затем постепенно на клиентских блоках, и уже в конце — на резервных. Так что если в клиентском блоке с новой версией ПО возникнут проблемы, мы можем перевести клиентов в резервный блок, со старой.
Когда на блок выкатывается новая функциональность, она не включается автоматически. Администраторы делают это с помощью флажков — feature toggle. Можно переключать клиентов на новую версию по группам — так мы проверяем реакцию обновлений на рост аудитории.
Сама по себе наша система надежна, но все еще зависит от бэкенда, который используется для проведения операций. Как защититься от проблем? Мы используем три инструмента.
А что если между запросом пользователя и восстановлением бэкенда произошли важные изменения? Например, сдвинулись курсы валют? В этом случае срабатывает двойная верификация. Данные операции сохраняются при вводе, а затем при исполнении сверяются. Если что-то не сходится, операция будут скорректирована или отклонена.
При использовании приложения это означает, что человек увидит состояние своего счета максимум через несколько секунд после входа. Хотя данные и могут быть несколько устаревшими. Если так произошло, то через несколько секунд данные обычно заменяются актуальными — значит, сервисная шина собрала все что нужно.
Кроме того, у нас работает предварительное кэширование с помощью репликации. В основном, для разных справочных данных. Мы заранее загружаем эти данные в бэкенд, клиент спокойно делает запрос на операцию, и мы его отправляем. Даже если системы, отвечающие за ведение данных, не работают, пользователю не придется лишний раз ждать.
В любом случае мы добиваемся того, чтобы максимально сократить ожидание пользователя — если вдруг есть проблемы, он сразу получает сообщение о невозможности операции. Мы стараемся свести количество таких сообщений к минимуму, поэтому увеличиваем время жизни некоторых кэшированных данных — это позволяет продлить нормальное взаимодействие с сервисами банка.
В некоторых сценариях кэшированием увлекаться не стоит — например, при выдаче наличных. Здесь возможно мошенничество со стороны клиента. Подобные операции в банкоматах и отделениях у нас не кэшируются. В интернет-банке с этим проще — мы принимаем заявку, потом обрабатываем ее или отклоняем.
В итоге, соблюдая принципы, описанные в статье, можно получить системы с доступностью 99,99% и выше.
Сейчас в планах — минимизировать time-to-market нашей единой системы, обеспечить омниканальность с учетом технических и бизнес-особенностей каналов. А также мигрировать легаси-системы с сохранением их работоспособности в процессе переезда.
Благодарим Романа Шеховцова за активную помощь в подготовке поста
Автор: Sberbank
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/proektirovanie-i-refaktoring/289105
Ссылки в тексте:
[1] Источник: https://habr.com/post/419815/?utm_campaign=419815
Нажмите здесь для печати.