Привет, меня зовут Александр Читалкин, и я руководитель офиса архитектуры в небольшом российском банке. Хочу рассказать об архитектуре «Платёжного сервиса» – системы оркестрации и проведения платежей. Разработка архитектуры велась в рамках проекта по модернизации существующего в банке решения. Работы были начаты в конце 2022 года и успешно завершились год спустя. Сейчас система находится в промышленной эксплуатации.

Несколько слов о банке для понимания масштаба. Банк работает преимущественно с физическими лицами, которым предлагает классические банковские продукты, а также инвестиционное обслуживание. Клиентская база – свыше 15 миллионов клиентов.

Предмет автоматизации

Среди услуг, которые банки предоставляют клиентам, немалая роль отводится приёму и обработке платежей и переводов – перечислению денег клиентов на счета как физических, так и юридических лиц, а также поставщикам услуг (например, сотовых операторов и служб ЖКХ).

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

Мастер-системы управляют так называемыми бухгалтерскими книгами (или «главными книгами»), где ведётся учёт движения средств по счетам банков, для простоты – «прихода» и «расхода». Таким образом, завершённая финансовая транзакция клиента (в конечном счёте) изменяет состояние главной книги.

За платежами и переводами стоит бизнес-процесс, цель которого – провести платёжное поручение клиента по всем внутренним проверкам и процедурам, а потом зафиксировать финансовый результат в главной книге. За автоматизацию этого процесса и отвечает платёжный сервис.

При этом к точности и скоординированности исполнения процесса предъявляются особые требования – деньги должны поступать получателю вовремя и в нужном количестве, не должно возникать путаницы. Банк также заинтересован в том, чтобы своевременно обнаруживать и пресекать незаконные и сомнительные операции.

Важно отметить, что в данном случае работа по автоматизации не затрагивала обработку карточных операций в рознице, то есть эквайринг. Эквайринг реализован отдельными инструментами и набором технологий.

Также платёжный сервис не отвечает за хранение и учёт информации по счетам и остаткам, являясь лишь оркестратором. В роли мастер-систем выступают автоматизированные банковские системы – АБС.

Платёжный процесс

Платёжный процесс от банка к банку, от типа к типу платежа может отличаться и содержать разное количество шагов. Например, при межбанковских переводах этапы зачисления и списания средств устроены иначе, могут содержать дополнительные проверки. Тем не менее, душа процесса может быть представлена в таком виде:

Платёжный процесс
Платёжный процесс
  • Поступившие платёжные поручения клиентов проходят проверку и предварительную обработку

  • Деньги списываются со счёта или временно блокируются на счёте отправителя в зависимости от типа платежа

  • Денежные средства зачисляются на счёт получателя

  • Платёж или перевод финализируется, в главной книге формируются бухгалтерские проводки

Некоторые свойства процесса

Важно отметить некоторые свойства нашего процесса, повлиявшие на принятие архитектурных решений:

  • Процесс не является интерактивным. Прямое взаимодействие клиента и платёжного сервиса в ходе обработки процессом не предусмотрено. Клиент формирует поручение в канале обслуживания, после чего получает результат операции — изменение остатка по своему счёту и уведомление от банка

  • Бизнес-процесс не содержит циклов и возвратов на предыдущие пройденные этапы. Он развивается в одном направлении, но может иметь ветвления и условные переходы

  • Процесс находится внутри одной транзакции и может считаться успешно завершённым только тогда, когда проведён полностью. Важно подчеркнуть, что «полностью» не всегда подразумевает зачисление средств в адрес получателя (например, при переводах в иностранные банки)

  • Процесс исполняется быстро – несколько секунд в течение операционного дня (когда банк работает)

Мотивация

На момент принятия решения о модернизации, за автоматизацию платёжных процессов отвечало монолитное приложение на стеке IBM в среде WebSphere Application Server (WAS) под управлением ОС AIX.

Компоненты мобильного и интернет-банка подключались к нему с использованием SOAP, передавая в обработку XML документ с платёжным поручением клиента.

В качестве СУБД использовалась Oracle. Модель данных состояла из совокупности различных деталей поручения, статусов и других бизнес-данных и технической информации, нужной в процессе обработки.

В общем виде архитектура выглядела следующим образом:

Архитектура устаревшего Платёжного сервиса
Архитектура устаревшего Платёжного сервиса

Основными причинами для глубокой переработки системы стали:

  • Недостаточная производительность. Если с онлайновой обработкой платежей система справлялась, то с пакетными операциями (например, с массовым зачислением зарплат) были трудности. Обработка пакета проходит в жёстких временных рамках, что удавалось обеспечить не всегда

  • Устаревший технологический стек. В текущей ситуации с доступностью продуктов IBM в РФ этот фактор получает особое значение

  • Низкая масштабируемость. Возможность наращивать производительность системы оказалась практически исчерпана. Кроме того, банк ожидал ввода новых категорий платежей, следовательно, существенного количества доработок на устаревшем решении. Связанный с этим низкий показатель T2M включён в общую проблему масштабируемости, только не по нагрузке, а по функциональности

Архитектурные принципы

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

В основу архитектуры легли следующие принципы:

  • Модульность. От «монолитного» подхода в целевом решении мы отказались. С другой стороны, цели «перейти на микросервисы» в их строгом каноническом представлении мы также не преследовали

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

  • Независимое масштабирование. Возможность наращивать скорость исполнения именно тех участков процесса, которые требуется ускорить прямо сейчас. Иначе, возможность повышения производительности наиболее востребованных модулей независимо от остальных

  • Независимые доработки. Рутинные доработки локализуются только в тех модулях, которые непосредственно отвечают за соответствующие участки процесса

  • Горизонтальное масштабирование. Поддержка возможности увеличения производительности решения за счёт добавления дополнительных модулей (копий) и включения их в параллельную обработку

  • Изоляция отказов. Полный отказ модуля и всех его экземпляров не должен приводить к отказу системы в целом или остановке всех платежей. Так, отказ модуля предварительной обработки не должен сказываться на платежах, которые уже прошли этот этап, и так далее

  • Отсутствие SPOF и узких мест в виде общей БД или какого-либо единого оркестрирующего звена

  • Минимальное технологическое разнообразие. Разнообразие технологий в составе общего решения должно быть сведено к минимуму. Сами технологии должны быть не только зрелыми, но и известными в достаточной мере службам развития и эксплуатации банка

Важно отметить, что платёжный сервис как таковой не является автономным. Он зависит от мастер-систем (АБС) банка, где непосредственно размещена главная книга, ведутся счета и остатки по ним. Поэтому качества новой системы будут несколько ограничены сверху возможностями АБС. Такое ограничение было принято потому, что проблемы платёжного сервиса влияли на эффективность процесса значительно сильнее, чем поведение АБС. А сами АБС при этом обладают существенно большим запасом прочности.

Ограничения

При проектировании также был принят ряд важных ограничений:

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

  • Платежи различных категорий должны переезжать в новую систему последовательно, не одновременно. Требовалось учитывать временное сосуществование и совместную работу двух систем – старой и новой

Целевая архитектура

Общая архитектура нового платёжного сервиса приведена на диаграмме:

Целевая архитектура нового платёжного сервиса
Целевая архитектура нового платёжного сервиса

Компоненты

Инфраструктура

Все компоненты новой системы размещаются на серверах архитектуры x86. Разработка основных модулей велась на стеке Java и Spring Boot, а развёртывание — в кластере OpenShift (был в банке на момент развёртывания). Виртуальные машины кластера распределены по инфраструктуре так, чтобы минимизировать масштаб влияния отказов аппаратуры на работоспособность системы.

API

Новый платежный сервис имеет собственный API, как и предшественник. API предназначен для ввода новых поручений и позволяет получать сведения по ранее отправленным платежам, а также манипулировать ими вручную при необходимости. Такой API реализуют два независимых модуля.

«Модуль приёма платежей» принимает поручение из сторонней системы, например, из ДБО (мобильного или интернет банка), и выполняет первичный контроль. Затем системе возвращается быстрый ответ в рамках одной синхронной сессии. Если проверки прошли успешно, начинается асинхронный процесс обработки, в противном случае – возвращается ошибка.

«Модуль консолидации» обслуживает информационные запросы, позволяет извлекать сведения по платежам по требованию и исторические данные. Также этот модуль отправляет уведомления и события по некоторым важным этапам процесса.

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

СУБД

В архитектуре нового сервиса применяется СУБД PostgreSQL. Эта БД никак не участвует в процессе обработки платежа, являясь лишь витриной для модуля консолидации. При недоступности БД этот модуль также не работает, но приём новых платежей и обработка старых не прекращается. 

Напрямую использовать эту БД в модулях запрещено. В архитектуре системы не предусматривается централизованное хранение каких-либо данных, необходимых при обработке, в общей БД (Kafka за скобками).

Интеграция

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

«Топик» (Kaka Topic) является основной конфигурационной единицей в архитектуре интеграции новой системы. Топик позволяет семантически развести потоки данных между модулями по отдельным логическим «каналам» в границах одного кластера Kafka.

Оркестрация

В архитектуре нового платёжного сервиса принято решение опереться на шаблон «хореография» без центрального оркестровщика. Шаблон отвечает принципам независимого масштабирования, разделения отказов и отсутствия SPOF. Кроме того, хореография лучше отвечает свойствам процесса.

Модули

Модули системы в совокупности реализуют все бизнес-процессы обработки платежей и переводов, а по отдельности – конкретные этапы или подпроцессы. Каждый модуль состоит из одной или нескольких функций, где каждая функция реализует подпроцесс общего платёжного процесса.

Функции опираются на Kafka Streams для потоковой обработки платежей.

Архитектура модулей

Модули обмениваются между собой некоторым объектом – документом в формате JSON. Объект является контейнером заданного формата и содержит:

  • Информацию о канале поступления (мобильный банк и другие)

  • Данные платёжного поручения клиента, такие как номера счетов, id клиента, сумма

  • Техническую информацию

  • Бизнес-статус

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

При определении общего состава и функциональной нагрузки модулей применялась следующая стратегия:

  • Этапы процесса, которые всегда и при любых обстоятельствах исполняются друг за другом и вместе («зацеплены»), остаются в одном модуле

  • Если процесс разветвляется на альтернативные цепочки, разделение модулей происходит в точке разветвления. Например, если после этапа проверки платёж может пойти по двум альтернативным маршрутам в зависимости от типа платежа, значит то, что следует после этого этапа, будет отделено

  • Модули должны выполнять определенную, выраженную, работу и изменять статус платежа. Например, если модуль принимает платёж в статусе «проверки пройдены», то подразумевается, что на выходе статус будет другой

Архитектура типового модуля показана на иллюстрации:

Общая архитектура типового модуля
Общая архитектура типового модуля

Общую логику работу каждого модуля можно описать следующим образом:

  1. Приём документа из входящего топика Kafka

  2. Выполнение функцией модуля работы, обмен с внешними системами

  3. Изменение бизнес-статуса

  4. Обогащение документа новыми данными

  5. Отправка обновлённого документа в исходящий топик

Подписки модулей

Каждый модуль подписан по меньшей мере на один входной топик. Считывание нового документа из входного топика является триггером, который приводит к запуску функций модуля. Конечный статус платежа является суперпозицией функций всех модулей, затронутых во время его проведения.

Входной топик одного модуля является также выходным для одного или нескольких соседних модулей.

Дополнительно, все без исключения модули работают со специальным топиком NOTIFY и некоторые — с необязательными служебными топиками для синхронизации и распределённых блокировок.

Композитные модули

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

Композитные модули применяются в тех случаях, когда, например, существует тривиальная альтернатива основной функции модуля (dummy), которую нет практического смысла выделять в отдельный модуль, и выбор нельзя сделать «без подсказки». Например, когда нужно пропустить документ ничего в нём не меняя, но при этом всё же переключить статус. Необязательные флаги в заголовке выступают в роли «подсказки», побуждая модуль изменить своё основное поведение.

Маршрутизация

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

У каждого топика есть модуль-подписчик, для которого этот топик является входным (точнее, все функционально идентичные экземпляры модуля в горизонтально масштабируемой среде). Также, каждый бизнес-статус может обрабатываться одним и только одним конкретным модулем. Так (неявно) устанавливается соответствие между статусом и модулем.

Принцип работы "маршрутизации"
Принцип работы "маршрутизации"

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

На текущей стадии реализации сервиса таблица маршрутизации содержится в конфигурации, общей для всех модулей.

Консолидация

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

Каждый модуль (кроме самого модуля консолидации) в обязательном порядке отправляет копию документа в NOTIFY. Модуль консолидации считывает этот топик, редуцирует поток документов от всех модулей, выделяя последний актуальный статус по каждому платежу, и обновляет свою витрину. История обработки также сохраняется.

Принцип работы "консолидации"
Принцип работы "консолидации"

Содержимое витрин используется для показа клиенту результатов проведения платежей и переводов в мобильном приложении и других каналах, для нужд сотрудников операционного блока и технической поддержки, а также при необходимости ручной обработки платежей.

Продолжение следует.

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


  1. BosonBeard
    02.09.2024 15:07

    Похоже на студенческий реферат.

    Но минусовать статью не стал


  1. Celios
    02.09.2024 15:07

    Очень странно видеть начало нового проекта с переездом на шифт в конце 22 года в банке. Кубер и тот под запретом, вместо него православный Deckhouse и иже с ними. И кафка в реестре рос. по отсутствует, вместо нее куча форкнутых решений от русских вендоров.

    Как вам в конце 22 года такой системный ландшафт в русском банке согласовали ? Тут, по моему, пахнет годом 17-19 не позже


  1. sdw
    02.09.2024 15:07

    Чем обусловлено использование Openshift? В последнее время коллеги из банков уходят с него в оригинальный k8s.


    1. DT0wer Автор
      02.09.2024 15:07

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