Архитектура
Архитектура микросервисов: как визуализировать сервисы и связи
Когда сервисов становится больше десятка, архитектура микросервисов перестаёт помещаться в голове, а общая схема превращается в клубок стрелок. Разберём, что показывать на схемах, какие виды схем нужны, как группировать сервисы по доменам и различать вызовы и события — и как не дать схеме отстать от системы.
На этой странице
- Почему микросервисы трудно нарисовать
- Что показывать на схеме микросервисов
- Сервисы и их владельцы
- Синхронные вызовы
- События и сообщения
- Данные
- Шлюз и внешние системы
- Одна схема — один вопрос: какие виды схем нужны
- Карта сервисов по доменам
- Поток событий
- Как не превратить схему в спагетти
- Как собрать карту сервисов по шагам
- Как поддерживать схему в актуальном виде
- Частые ошибки
- Чек-лист схемы микросервисов
- Вопросы и ответы
Почему микросервисы трудно нарисовать#
В монолите архитектура видна из структуры кода: открыл проект — и вот модули. В микросервисах система разбросана по десяткам репозиториев, команд и баз данных. Каждый сервис по отдельности простой, а сложность переехала в связи между ними: кто кого вызывает, кто на какие события подписан, чьи данные где лежат.
Поэтому привычный способ «нарисуем всё на одной схеме» здесь не работает. Тридцать сервисов, сто связей, три вида взаимодействия — получается схема, которую автор понимает, а остальные вешают на стену для красоты. Хорошая визуализация микросервисов — это не одна картинка, а несколько схем, каждая из которых отвечает на свой вопрос.
Если вы только начинаете рисовать архитектуру и сервисов немного, сначала прочитайте общую статью как нарисовать архитектуру приложения: уровни детализации и обозначения из неё работают и здесь. Ниже — то, что добавляется, когда частей становится много.
Что показывать на схеме микросервисов#
У микросервисной системы пять видов элементов, которые почти всегда стоит показать. Не обязательно на одной схеме — но про каждый нужно решить, где он нарисован.
Сервисы и их владельцы#
Каждый сервис — отдельный блок с понятным именем по его задаче: «Заказы», «Каталог», «Уведомления», а не «svc-17». В описании — язык и основное хранилище, рядом — команда-владелец. Владелец важнее технологии: когда сервис падает, первым делом ищут, кому писать.
Синхронные вызовы#
HTTP-запросы, gRPC — вызывающий сервис ждёт ответа. Такие связи создают жёсткую зависимость: если вызываемый сервис тормозит, тормозит и цепочка над ним. На схеме это сплошная стрелка от вызывающего к вызываемому с подписью протокола.
События и сообщения#
Сервис публикует событие в брокер — Kafka, RabbitMQ, NATS — и не ждёт, кто и когда его обработает. Подписчики узнают о нём сами. Это ослабляет связность, но делает поток менее заметным: в коде публикующего сервиса не видно, кто его слушает. Поэтому события на схеме особенно ценны. Брокер рисуют отдельным блоком, связи — пунктиром, а на связи пишут название события.
Данные#
Обычное правило микросервисов — у каждого сервиса своя база, и другие сервисы в неё не ходят. На схеме сервисов базы удобно не рисовать отдельными блоками, а писать в описании сервиса: «Go · PostgreSQL». Если два сервиса всё же делят одну базу, это стоит показать явно — это слабое место, о котором должна знать вся команда.
Шлюз и внешние системы#
API-шлюз — единая точка входа для клиентов: маршрутизация, проверка прав, ограничения частоты. Внешние системы — платёжный провайдер, почта, SMS, службы доставки — рисуют нейтральным цветом на краю схемы: их поведение вы не контролируете, а отказ любой из них должен быть учтён.
Одна схема — один вопрос: какие виды схем нужны#
Для большинства команд хватает первых двух. Схема потоков данных нужна, когда важно, где лежат персональные данные и куда они передаются, — для неё есть отдельная нотация DFD и шаблон DFD, а как работать с такими схемами на доске — на странице диаграмма потоков данных онлайн. Схему развёртывания обычно ведут те, кто отвечает за инфраструктуру, и смешивать её с логикой сервисов не стоит.
Карта сервисов по доменам#
Группировка по доменам — главный приём против хаоса. Домен — область бизнеса со своим языком и своей командой: покупки, витрина, логистика. Внутри группы сервисы связаны тесно, между группами — как можно реже и лучше через события. На такой карте сразу видно, где граница ответственности и какие связи её пересекают.
Поток событий#
Эту схему рисуют от события, а не от сервиса: «что случится, когда создан заказ?». Она отвечает на вопросы, которые на карте сервисов не видны: кто ещё подписан на событие, в каком порядке идут реакции, что сломается, если изменить формат события. Для разбора сложного сценария полезно рисовать такую схему на каждый ключевой бизнес-процесс отдельно.
Как не превратить схему в спагетти#
- Группируйте по доменам, а не по технологиям. Рамка «Логистика» полезнее рамки «Сервисы на Kotlin».
- Прячьте инфраструктуру. Балансировщики, сетевые прокси, сбор логов и мониторинг — на схему развёртывания, а не на карту сервисов.
- Подписывайте протоколы: REST, gRPC, название события. Без подписи непонятно, что сломается при отказе.
- Разделяйте виды связей стилем линии: сплошная — синхронный вызов, пунктир — событие. Договорённость — в легенде.
- Рисуйте брокер одним блоком. Вместо десятка стрелок «каждый с каждым» — стрелки в брокер и из него.
- Не показывайте всё сразу. Второстепенные связи уберите или вынесите на отдельную схему конкретного процесса.
Так хуже
Так лучше
Как собрать карту сервисов по шагам#
Составьте список сервисов
Из репозиториев, каталога сервисов или описания развёртывания. У каждого — имя, команда, язык, основное хранилище.
Разложите по доменам
Объедините сервисы в группы по области бизнеса. Если сервис не ложится ни в одну группу, это повод обсудить, чей он.
Добавьте входы
Клиентов, API-шлюз и внешние системы. Внешние — нейтральным цветом на краю схемы.
Проведите синхронные вызовы
Сплошными стрелками от вызывающего к вызываемому, с подписью протокола. Начните с основных путей пользователя.
Нарисуйте события
Брокер — отдельный блок. Стрелки пунктиром: от публикующего в брокер и из брокера к подписчикам, на связи — название события.
Добавьте легенду и дату
Что значат цвета, пунктир и группы. Дата обновления — чтобы читатель знал, насколько схеме можно верить.
Проверьте с командами
Покажите карту владельцам сервисов. Каждая команда легко найдёт ошибки в своей части — и часто узнает о подписчиках, о которых не подозревала.
Начать можно с шаблона «Архитектура ПО»: группы, карточки с иконками и подписанные связи уже есть, остаётся переименовать и размножить. Как пользоваться метками, цветами и анимацией связей на доске, — в руководстве «Схема архитектуры сервиса». Попробовать можно сразу и без регистрации — в песочнице на главной.
Как поддерживать схему в актуальном виде#
В микросервисах схема устаревает быстрее, чем в монолите: сервисы появляются, делятся и исчезают, у событий появляются новые подписчики. Полностью автоматической и при этом понятной человеку схемы не бывает, поэтому работают сочетания.
- Владелец у каждой схемы. Карта сервисов — у архитектора или техлида, схемы событий — у команд, чьи процессы на них нарисованы.
- Правка в той же задаче. Добавили сервис или событие — поправили схему, как документацию.
- Текст рядом с кодом. Небольшую схему одного домена удобно хранить в репозитории текстом Mermaid — подробнее в статье синтаксис Mermaid: примеры и шпаргалка. Блок-схему из такого текста NodePanel вставит на доску блоками, связями и группами, а доску можно скопировать обратно текстом.
- Регулярная сверка. Раз в квартал пройдитесь по карте с командами: что появилось, что умерло.
Карта кода — для обзора одного сервиса. Карта кода в NodePanel разбирает папку или zip-архив одного проекта прямо в браузере и строит доски: страницы, маршруты API, вызовы с фронта, таблицы базы и архитектуру — сервисы из docker-compose и зависимости между папками кода. Для микросервиса это быстрый способ увидеть его маршруты и данные, а для монорепозитория с docker-compose — список сервисов.
Частые ошибки#
- Одна схема на всё. Сервисы, события, базы и серверы вместе — нечитаемо. Разведите вопросы по разным схемам.
- Вызовы и события выглядят одинаково. Тогда схема не отвечает на главный вопрос: что упадёт вместе с этим сервисом.
- Брокер как невидимка. События нарисованы стрелками напрямую между сервисами, как будто это вызовы.
- Нет владельцев. Видно, что сервис есть, но непонятно, кто за него отвечает.
- Группировка по технологиям. Рамки «Java» и «Go» ничего не говорят о том, как устроен бизнес.
- Общая база не отмечена. Два сервиса пишут в одну таблицу, а на схеме они независимы.
- Инфраструктура вперемешку с логикой. Прокси, сети и мониторинг заслоняют то, ради чего схему открыли.
- Схема без даты. Через полгода никто не знает, можно ли ей верить.
Чек-лист схемы микросервисов#
- Понятно, на какой вопрос отвечает схема: карта сервисов, поток событий, данные или развёртывание.
- Сервисы сгруппированы по доменам, у каждой группы есть команда-владелец.
- У каждого сервиса — имя по задаче, язык и основное хранилище.
- Синхронные вызовы и события различаются стилем линии, есть легенда.
- На каждой связи — протокол или название события.
- Брокер нарисован отдельным блоком, события идут через него.
- Шлюз и внешние системы показаны, внешние — нейтральным цветом.
- Общие базы и другие слабые места отмечены явно.
- Инфраструктура вынесена на отдельную схему.
- Есть дата обновления и владелец схемы.
Если нужна общая доска, где команды правят и обсуждают карту сервисов вместе, — посмотрите страницу схема архитектуры ПО онлайн.
Вопросы и ответы#
Нужно ли рисовать базы данных микросервисов отдельными блоками?
На карте сервисов обычно нет: достаточно указать хранилище в описании сервиса. Отдельными блоками базы стоит рисовать, если их делят несколько сервисов или если схема отвечает на вопрос о данных.
Как показать на схеме асинхронные события?
Нарисуйте брокер отдельным блоком и проведите к нему и от него пунктирные стрелки с названием события. Сплошные стрелки оставьте для синхронных вызовов и опишите это в легенде.
Сколько схем нужно для микросервисной системы?
Обычно хватает карты сервисов по доменам и нескольких схем потоков событий для ключевых процессов. Схемы потоков данных и развёртывания добавляют, когда о них регулярно спрашивают.
Может ли карта кода NodePanel построить схему всех микросервисов?
Нет. Карта кода разбирает один проект за раз прямо в браузере и показывает его маршруты, вызовы, данные и архитектуру, включая сервисы из docker-compose. Реальный трафик между сервисами она не видит, поэтому общую карту собирает человек.
Как не запутаться, если сервисов больше пятидесяти?
Сделайте верхнюю карту только из доменов и связей между ними, а для каждого домена отдельную подробную схему. Тогда на каждой схеме будет не больше полутора десятков блоков.