Привет! Меня зовут Алина, я работаю техническим писателем в компании Quadcode. В этой статье хочу поделиться опытом верхнеуровневого описания архитектуры системы с использованием структуры C4. Небольшая оговорка: предпринятые шаги включают в себя определенные отходы от канонической нотации в угоду удобству и особенностям системы.

Для справки:

HLD (high-level design) – верхнеуровневое описание архитектуры системы, где представлены основные компоненты и их взаимодействия. 

LLD (low-level design) – низкоуровневое детальное описание каждого из компонентов системы.

Созданием HLD-документации предполагалось закрыть следующие потребности:

  1. Собрать воедино информацию по устройству системы на bird’s-eye уровне для общего понимания.

  2. Снизить порог вхождения в предметную область для новых сотрудников.

  3. Иметь возможность предоставлять блоки HLD-документации по запросу регуляторов.

Особенности 

Одной из самых непростых особенностей можно назвать солидный срок жизни платформы: к моменту старта работы она благополучно функционировала в течение 8 лет (и продолжает, собственно), что внесло коррективы в подход к описанию. Большинство нотаций говорят в первую очередь о проектировании, т.е. о схематичном общем устройстве системы, которую еще только предстоит реализовать. Здесь же было необходимо описать архитектуру вполне реального, сложносочиненного финтех-продукта, который за время своего существования успел обрасти рядом легаси, постоянно расширялся с бизнесовой точки зрения, а архитектура сменила парадигму своего существования и перешла с монолита на микросервисы.

Вытекающая из первой особенность номер два: какие домены выделить в системе на верхнем уровне? Что считать отдельным направлением, а что – зависимой частью? Критерии, на основе которых стоило выделить основные направления, в команде архитектуры отличались, к общему мнению еще только предстояло прийти.

Нотации

Прежде чем остановиться на C4, было проведено небольшое исследование общепринятых нотаций описания архитектуры системы. Среди основных можно выделить:

Представленные выше модели обладают общими чертами, к примеру, практически везде присутствует деление на уровни: Logical/Conceptual/Contextual, которые переходят на более низкий уровень, i.e. Domain/Process -> уровень Development.

Нотация C4 не является чем-то инновационным по сравнению с представленными выше структурами описания, но выглядит демократичнее.

C4

Немного общих слов про нотацию, поскольку про нее отдельно уже писали и не раз. Итак, C4 - один из способов визуализации архитектуры программного обеспечения. В названии кроется структура нотации: Context+Container+Component+Code=С4. Представлена широкой публике недавно, в 2018 году, является деривативом нотации 4+1. Подробное описание компонентов диаграмм всех уровней есть на github по ссылке. Для HLD-документации мы взяли первые два уровня - “контекст” и “контейнеры”. “Компоненты” и “код” логически больше подходили под LLD-направление, поэтому в скоуп задачи они не вошли.

Контекст

После определенных дискуссий было решено выделить основные домены платформы, которые обладали высоким уровнем самодостаточности, а именно:

  • Trading Platform: торговые инструменты, администрирование, биллинг, комплаенс, антифрод.

  • Affiliate Program: инструмент для работы с партнерами по привлечению новых пользователей на платформу.

  • Analytics: инструменты сбора и анализа данных на платформе, куда входят направления Data Platform, Data Science Dev, Insights&Experiments.

  • Transport Infrastructure: внутренняя транспортная система (шина данных), а также инструменты Retention, которые логически подпадают под определение транспорта сообщений.

  • Banking: инструменты по интеграции с платежными методами, проведение SWIFT/SEPA платежей, онлайн банкинг.

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

Кстати, границы могут быть вложенными:

Boundary(c1, "Transport Domains"){ 

Boundary(c2, "Transport Management System"){ 

System(transportAdmin, "Bus-kit", "Manages transport messages/permissions")

System(consul, "Consul", "Provides information on microservices")

 }

System(internalTransport, "Internal Transport", "Transfers messages between microservices") 

System(externalTransport, "External Transport", "Transfers messages to external clients")

 }

Основные элементы диаграммы контекстного уровня:

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

  • System_external (не представлен на диаграмме) - внешний сервис, взаимодействующий с одним или несколькими элементами системы.

  • Boundary - граница, включающая в себя ряд логически объединенных элементов.

Контейнеры

За основные элементы диаграммы контейнеров было решено взять микросервисы, СУБД, а также SPA, landings, клиентские приложения для ряда случаев (как отправная точка). В зависимости от обширности домена количество контейнерных диаграмм может разниться. К примеру, в партнерской программе их 2, а в торговой платформе - 10. Если брать в качестве примера домен торговой платформы, логически диаграммы этого уровня были разделены на:

  • Торговые инструменты - Margin Forex, CFD, Options;

  • Compliance - GDPR, верификация пользователей, etc;

  • Backoffice - администрирование;

  • Antifraud - борьба с мошенничеством;

  • Billing - депозиты/выводы средств, подключение новых платежных методов;

  • Trading Activity - обучающие видео, финансовые календари и т.д.;

  • Retention/acquisition - инструменты по удержанию пользователей на платформе.

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

Если у микросервиса, входящего в домен, есть своя база данных, ее необходимо отразить на схеме. Если компонент взаимодействует с большим количеством внешних по отношению к нему сервисов, для сохранения читабельности диаграммы можно объединить эти сервисы в логически определенный элемент, как, например, это было сделано с Product Microservices на части диаграммы ниже.

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

К элементам контекста на уровне контейнеров добавляются новые:

Container - логически определенный элемент, основная единица диаграммы;

ContainerDb - база данных того или иного контейнера или отдельно стоящая СУБД для ряда случаев (i.e. Cassandra).

Для более удобного расположения элементов диаграммы можно использовать направления ..._Right, _Left; _Down; _Up и т.д. при обозначении взаимодействия:

Rel_Right(paymentProcessing, paymentProcessingDb, "Reads, writes to")


Каждую диаграмму на обоих уровнях сопровождает текстовое описание, где кратко указано назначение того или иного элемента и его взаимодействия. Если элемент взаимодействует с рядом внешних сервисов, их стоит указать в тексте, чтобы не “мусорить” в диаграмме. Это же правило касается и интегрируемых административных панелей, число которых может доходит до нескольких десятков. 

Как использовать

Если вы пользуетесь внутренней вики на базе Confluence (как мы), диаграммы легко строить с помощью плагина PlantUml, достаточно вставить референс 

!includehttps://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml 

в код диаграммы, чтобы пользоваться элементами C4. Можно также использовать всем известный сервис draw.io, где диаграммы строятся не кодом, а блоками. 

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

Обновление

Что

Одна из (если не главная) боль подобной документации - поддержание ее актуального состояния. Плюсом именно HLD-документации является ее не столь стремительные изменения: в рамках верхнего уровня (контекста) ситуация меняется довольно редко, уровень контейнеров более подвижен, но и там можно справиться с потоком обновлений, если четко определить, что считать изменением.

Поскольку за основную единицу уровня контейнеров был взят микросервис, изменениями решено считать:

  • Введение/выведение из эксплуатации микросервисов;

  • Интеграция сервисов с новыми внешними провайдерами; 

  • Изменение зависимостей между микросервисами;

  • Переход на новые административные панели в микросервисах.

Когда

На этапе квартального планирования каждая фича проходит архитектурное ревью, в рамках которого команда архитекторов проверяет техническое решение (подробнее о процессе стоит рассказать отдельно) и помечают фичу флагом ArchIsChanged в таск-трекере (мы используем Target Process). Когда фичи проверены и собраны в список, мы вместе с архитектурной командой возвращаемся к нему в конце квартала и смотрим, что удалось сделать, и что именно поменялось в итоге. Список реализованных фич за предыдущий квартал проходит дополнительную проверку на случай, если где-то флаг забыли поставить или по итогам разработки той или иной фичи были выявлены изменения, которые не упоминались в изначальном тех.решении - we are human after all.

Выводы и планы на будущее

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

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

В планах расширить HLD-документацию и добавить направление Infrastructure, а также понять, как лучше подойти к описанию LLD-документации.

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