Создание микросервисной архитектуры: промт с диаграммами в PlantUML

Спросите у модели микросервисную архитектуру — получите набор сервисов, названных по сущностям: users, orders, products, notifications. Выглядит аккуратно, работает плохо. Такая нарезка почти гарантирует, что любое изменение бизнес-процесса заденет три сервиса сразу, а каждый запрос превратится в цепочку сетевых вызовов.
Границы сервиса проходят не по сущностям, а по данным, которые меняются вместе, и по командам, которые за них отвечают. Значит, и промт должен начинаться с данных.
Шаг 1. Границы по данным, а не по существительным
Ты — архитектор. Помоги найти границы сервисов для системы [описание]. ВХОДНЫЕ ДАННЫЕ: Бизнес-процессы: [перечислить основные сценарии от начала до конца] Данные: [основные сущности и их атрибуты] Что меняется часто: [какие части системы правят чаще всего] Команды: [сколько людей и кто за что отвечает] Нагрузка: [где она реально высокая] ЗАДАЧА: Определи группы данных, которые изменяются в одной транзакции и не могут быть разделены без потери согласованности. Для каждой границы: почему она проходит здесь, что окажется внутри, какие запросы станут сетевыми и чем это грозит. Отдельно: какие из предложенных границ сомнительны и при каком условии их лучше не проводить. Не предлагай сервисов, чья единственная задача — CRUD над одной таблицей.
Последний запрет отсекает половину типичных «архитектур»: сервис, который только читает и пишет свою таблицу, — это не сервис, а слой доступа к данным, вынесенный за сеть.
Шаг 2. Честный разговор о цене
Для предложенного разбиения перечисли, что станет сложнее по сравнению с монолитом. Конкретно: какие операции потеряют транзакционность и как их придётся переделать; где появится согласованность в конечном счёте и что увидит пользователь в промежутке; сколько сетевых вызовов будет в самом частом сценарии; что понадобится для отладки распределённого запроса; как выкатывать несовместимые изменения контрактов. Оцени, какой минимальный набор инфраструктуры нужен, чтобы это эксплуатировать. В конце ответь прямо: оправдано ли разделение при команде в [N] человек, или разумнее модульный монолит.
Последний вопрос стоит задавать всерьёз. Микросервисы решают организационную задачу — дать командам работать независимо. При команде из пяти человек они добавляют инфраструктурную сложность, не решая никакой проблемы.
Шаг 3. Контракты до диаграмм
Опиши контракты между сервисами. Для каждого взаимодействия: синхронное или через события, и почему именно так. Для синхронных: метод, входные и выходные данные, коды ошибок, тайм-аут, поведение вызывающего при недоступности. Для событий: имя события в прошедшем времени, состав полезной нагрузки, кто публикует, кто подписан, что делать при повторной доставке. Отметь взаимодействия, где синхронный вызов создаёт цепочку зависимостей длиннее двух звеньев.
Шаг 4. Диаграмма
Собери диаграмму в PlantUML. Компоненты — сервисы, стрелки — взаимодействия, сплошные для синхронных вызовов, пунктирные для событий. Подпиши на каждой стрелке, что передаётся. Хранилища показывай отдельными элементами, привязанными к своему сервису: общая база у двух сервисов должна быть видна на схеме как проблема. Добавь легенду. Код должен компилироваться без внешних библиотек.
Требование показывать хранилища отдельно — способ увидеть главный антипаттерн. Если два сервиса ходят в одну базу, они не независимы, и на диаграмме это должно бросаться в глаза.
Что проверить в получившейся схеме
| Проверка | Плохой признак |
|---|---|
| Длина цепочки вызовов | Больше двух синхронных звеньев подряд |
| Общие хранилища | Есть хоть одно |
| Двусторонние связи | Сервисы вызывают друг друга |
| Центральный узел | Один сервис связан со всеми |
| Изменение процесса | Правка одного сценария трогает больше двух сервисов |
Последняя строка — главный тест. Возьмите реальное изменение из вашего бэклога и проведите его по схеме. Если оно задевает половину системы, границы проведены не там, и лучше узнать это сейчас, а не через год.