D-05 · Границы на старте#
- Версия: 4.0 · 2026-09-22 · по мастер-шаблону v6.0
- Известно также как: границы на гринфилде, с чего начать декомпозицию, «монолит или сразу микросервисы»
- Этап: W4 · Верхнеуровневая архитектура
- Стадия: гринфилд — истории нет по условию; где резать работающую — D-02
- Профиль: дорого изменить · высокое влияние → полная форма
- Не решает: где резать уже работающую систему — это D-02; как части будут разговаривать — D-04; делятся ли данные — D-07
- Не путать с: D-02 · Границы сервисов в работающей системе — там границы режут по измерению, здесь закладывают предсказанием
- Карточки: ARCH-01 монолит и микросервисы · ARCH-02 границы и ограниченный контекст · ARCH-03 внутренняя архитектура сервиса · ARCH-13 strangler fig
Почему это отдельное решение, а не ветка в D-02. Там вопрос «где резать», и отвечает на него история изменений. Здесь истории нет: нет репозитория, нет трекера, нет схемы. Вопрос другой — какие границы заложить, — и источник фактов другой: не измерение, а предсказание по требованиям и языку. Разные вопросы, разные дисквалификаторы, противоположные эвристики при нехватке данных.
Ответ известен заранее в большинстве случаев — модульный монолит. Документ нужен не чтобы его получить, а чтобы получить вместе с ним: границы модулей, условие перехода и запись о том, какая граница окажется самой дорогой.
1. Что выяснить#
Пять вопросов вместо семи: на гринфилде меньше источников. Все отвечаются до написания первой строки кода.
| Вопрос | Где искать ответ | Заполняет ось |
|---|---|---|
| Где одно и то же слово означает разное? | Требования, разговоры с заказчиком, спор о терминах на встрече | Языковая граница |
| Что обязано меняться атомарно и какие инварианты нельзя нарушать? | Требования из W0 | Транзакционная граница |
| Сколько команд будет и когда появится вторая? | План найма, а не текущий состав | Организационное соответствие |
| Что по плану будет переписываться в первый год? | Роадмап продукта | Ожидаемая скорость изменений |
| У каких частей профиль нагрузки или требования к доступности различаются на порядок? | Оценки W1 | Технические причины разделения |
Ответы на первые два — факты, на остальные три — предсказания. Различие помечается: [требования] и [орг] против [прогноз]. Ось, заполненная одними прогнозами, не может перевесить ось, заполненную фактами, — иначе решение принимается по плану найма, который изменится раньше, чем система запустится.
Вопросы, порождающие кандидатов#
- Если резать по языку — сколько получится частей и какие?
- Если по транзакционным границам — какие?
- Что останется, если не резать вовсе?
Третий вопрос обязателен: он и даёт нулевой вариант.
2. Оси и дисквалификаторы#
Оси сравнения. Языковая чистота · транзакционная целостность · организационное соответствие · стоимость ошибки · скорость первого запуска.
Осей пять, а не восемь как в D-02: связность изменений, глубина синхронной цепочки и стоимость перехода требуют истории и здесь неизмеримы. Ось, которую нечем заполнить, вычёркивается, а не заполняется прогнозом.
Дисквалификаторы. На гринфилде срабатывают почти исключительно организационные. Каждый называет, что именно отвергает — разрез целиком, число частей, отдельную часть, линию, основание линии или требование: дисквалификатор, из которого непонятно, что отвергнуто, — наблюдение, а не правило.
- Нет наблюдаемости, трассировки и автоматического выката. Для микросервисов это входное требование, а не следствие (OPS-07); у системы, которой ещё нет, его нет по определению. Отвергается разрез целиком — и это единственный из семи, который можно не отвергнуть, а купить: построить входное требование до запуска. Цена покупки называется в ADR, иначе отвержение считается состоявшимся.
- Сервисов получается больше, чем команд. Одна команда на два сервиса — это не два владельца, а один владелец с двойной эксплуатацией. Отвергается число частей, а не разрез: частей не больше, чем владельцев, и линия перепроводится так, чтобы это выполнялось.
- У части нет владельца — некому дежурить и отвечать за контракт. Отвергается эта часть, а не разрез: она присоединяется к соседней, у которой владелец есть.
- Разрез разрывает операцию, обязанную быть атомарной в основном сценарии (DIST-08). Отвергается линия, а не требование атомарности — как и в D-02, D-07: инвариант не обсуждается, обсуждается место разреза.
- Разрез идёт по техническим слоям — даёт связность на каждое изменение. Отвергается основание линии, а не сама идея резать: линия перепроводится по предмету, а не по слою. Это единственный дисквалификатор, у которого нет законного исхода «оставить как есть»: слой границей не бывает никогда.
- Планируемый разрез рассекает класс защищаемых данных. На старте это дешевле всего исправить и легче всего проглядеть: классов ещё нет в схеме, они есть только в требованиях. Отвергается положение линии: её двигают, а не оплачивают. Персональные, платёжные и подобные данные стягиваются в одну границу до первой строки кода — потом это миграция (D-07).
- Части с разными целями по доступности остаются в одном архитектурном кванте — общая база, общий выкат, синхронная связь на каждой операции. На старте это встречается чаще, чем кажется: границы нарисованы, а база одна на всех.
У последнего два выхода, и они противоположны — поэтому правило выбора записано здесь. Отвергается либо квант, либо различие в требованиях:
- разрез возможен (дисквалификаторы 1–3 не сработали или куплены) → разрезается квант: части с разными целями получают свои базу и выкат;
- разрез невозможен → отзывается различие: у частей одна цель по доступности, и та, что слабее, живёт по цели той, что строже.
Отзыв различия — решение, а не умолчание: он записывается в ADR строкой «у части N нет собственной цели по доступности, она живёт по цели M», и с этого момента обещать разные цифры нельзя ни в требованиях, ни в
D-10. Молчаливый отзыв — это те самые «разные цифры в требованиях, недостижимые с первого дня».
Силы интеграции: на старте их измеримо две из четырёх#
D-02 взвешивает силы разделения против сил интеграции. Здесь половина этого списка неизмерима по той же причине, по которой вычеркнуты три оси, — измерять нечего.
| Сила | На старте | Что делать |
|---|---|---|
| Транзакции | Измерима: инварианты известны из W0 | Работает дисквалификатором, как и в D-02 |
| Рабочий процесс | Измерима прогнозом: основные сценарии описаны, частоты оценены на W1 | Пометка [прогноз]; пересечение линии на каждой операции основного сценария — довод против линии |
| Общий код | Неизмерима: кода ещё нет | Не заполнять и не выдумывать. Проверить при первом же пересмотре границ — к тому времени он появится и уже будет общим |
| Отношения в данных | Неизмерима как факт, но является нашим решением: схему проектируем мы | Не «какие связи есть», а «какие связи мы собираемся провести поперёк линии» — и если собираемся, линия под вопросом |
Последняя строка — единственное место, где гринфилд даёт преимущество. В работающей системе отношения в данных — факт, который приходится оплачивать. Здесь это ещё выбор, и он бесплатен ровно до первой миграции.
3. Матрица оценки#
Колонки — кандидаты из раздела 1, обязательно включая нулевой вариант. В ячейках факты с пометкой источника.
- Словарь пометок:
[требования]— из инвариантов и формулировок W0 ·[орг]— из состава команд и принятой терминологии ·[прогноз]— предсказание с указанием, чем оно подтвердится после запуска ·[нет данных].
Пример условный. Форма настоящая, содержание — иллюстрация.
| Ось | Что записывать в ячейку | Модульный монолит | Разрез по языку |
|---|---|---|---|
| Языковая чистота | Сколько терминов остаётся с двойным значением внутри границы | 3 — границы внутри процесса не мешают им пересекаться [орг] |
0 — разрез строился по языку [орг] |
| Транзакционная целостность | Какие атомарные операции пересекают границу | Ни одной — один процесс | Одна: подтверждение резерва билетом [требования] |
| Организационное соответствие | Сколько команд на сколько частей, и когда появится вторая | Одна команда, одна кодовая база | Одна команда на три сервиса [орг] |
| Стоимость ошибки | Что придётся сделать, если граница окажется ложной | Перенести модуль — дни | Перенести между сервисами — недели плюс миграция данных |
| Скорость первого запуска | Что нужно построить до первой выкатки | Ничего сверх приложения | Наблюдаемость, трассировка, автовыкат — до запуска |
- Матрица чаще всего не понадобится: дисквалификаторы отсекут разрезы раньше. Тогда она не заполняется, а вместо неё пишется строка «дисквалификаторы сделали всю работу» с перечнем сработавших (мастер-шаблон).
4. Типовые формы разреза — и какие из них применимы без истории#
Те же формы, что в D-02, раздел 4, но половина из них требует данных, которых на старте нет.
| Форма | Применима на старте | Почему |
|---|---|---|
| По поддомену и ограниченному контексту | Да | Язык существует до кода: он в требованиях и в головах заказчика |
| По транзакционной границе | Да | Инварианты формулируются в W0, до первой строки |
| По бизнес-способности | Да, с оговоркой | Способности стабильнее команд, но на старте их легко перечислить неверно |
| По владению данными | Частично | Модель данных ещё меняется; граница закрепит незрелое решение |
| По скорости изменений | Нет | Требует истории. Роадмап — не история, а намерение |
| По команде | Нет | Команда одна; план найма меняется чаще, чем архитектура |
| По профилю нагрузки | Нет | Оценки W1 — расчёт, а не замер. Кроме того, у выделяемой части должны быть свои данные, иначе это кэш |
| По техническим слоям | Никогда | Анти-форма |
Применимых форм ровно две с половиной, и обе дают границы внутри процесса ничуть не хуже, чем между сервисами. Это и есть главный аргумент за модульный монолит: дисциплина границ достижима сразу, а цена ошибки отличается на порядок.
5. Эвристики#
Умолчание — модульный монолит с явными границами модулей. Не из консерватизма: из пяти осей две заполняются фактами, три — прогнозами, а прогнозы на старте ошибаются. Модульный монолит сохраняет право на ошибку (ARCH-01), не отказываясь от дисциплины: модули с явными интерфейсами, запрет на чужие таблицы, проверка зависимостей на сборке.
Границы из языка переживут переход. Единственный источник фактов, доступный до запуска, — то, как заказчик называет вещи. Найденная по языку граница останется верной и после того, как появятся измерения; найденная по прогнозу нагрузки — нет.
Отклонение от умолчания требует названного дисквалификатора у монолита, а не достоинства у разреза. «Микросервисы масштабируются лучше» — не основание, пока не названо, что именно не масштабируется. Настоящие основания редки и почти всегда организационные: две команды с первого дня, юридически обязательная изоляция части данных, часть системы пишет чужая команда.
Проверка зависимостей на сборке делается в первый месяц. Отложенная, она не делается никогда, и через полгода модули окажутся монолитом без границ. Это единственная работа из этого решения, которую нельзя отложить.
Записать, чем решение станет проверяемым. Через полгода появится история изменений — и вопрос перейдёт в D-02. Здесь надо записать порог: какую долю изменений внутри одного модуля мы считаем приемлемой.
6. Запись в ADR#
| Поле ADR | Чем заполняется отсюда |
|---|---|
| Контекст | Ответы на пять вопросов, с пометками [требования] / [орг] / [прогноз] |
| Дисквалификаторы | Что отсекло разрезы; обычно это входные требования микросервисов |
| Рассмотренные варианты | Кандидаты и принцип каждого; матрица — если заполнялась |
| Решение | Перечень модулей с владением данными: кто чем владеет и к чему не имеет права обращаться |
| Обоснование | Какие оси заполнены фактами, какие прогнозами, и почему прогнозы не перевесили |
| Самая дорогая будущая граница | По какой линии разрез обойдётся дороже всего — обычно по ней идёт транзакция основного сценария |
| Последствия | Что придётся построить в первый месяц; что станет дороже при росте |
| Условия пересмотра | Раздел 7 |
| Метод | D-05 v<версия> · шаблон ADR v<версия> — рыночного снимка нет |
7. Условия пересмотра#
- Появилась история изменений — через полгода-год эксплуатации. Решение перестаёт быть предсказанием и переходит в D-02, где его можно измерить.
- Появилась вторая команда-владелец.
- Построены наблюдаемость, трассировка и автоматический выкат — снят главный дисквалификатор.
- Доля изменений внутри одного модуля упала ниже записанного порога.
- Профиль нагрузки частей разошёлся на порядок по замеру, а не по оценке.
Проверка перед тем, как считать решение принятым — пять пунктов в шаблоне.
- Источники: Martin Fowler — MonolithFirst · Eric Evans — Domain-Driven Design · Sam Newman — Building Microservices ·
D-02(формы разреза, откуда взята таблица раздела 4)
История версий#
| Версия | Дата | Изменение |
|---|---|---|
| 4.0 | 2026-09-22 | MAJOR, по итогам прогона U-02, развилка Р2. Все семь дисквалификаторов переписаны так, что каждый называет отвергаемое — разрез, число частей, часть, линию, основание линии или требование. У седьмого, о разных целях по доступности в одном кванте, выходов оказалось два и противоположных; правило выбора записано явно, а отзыв различия объявлен решением, а не умолчанием, и обязан попасть в ADR строкой. У первого названа цена покупки: он единственный, который можно не отвергнуть, а оплатить. Старым ADR: он один — ADR-0004 прогона U-02; седьмой дисквалификатор там сработал, выход выбран верно (разрез был невозможен, отозвано различие) и записан строкой, как теперь и требуется. Перепроверять нечего |
| 3.0 | 2026-09-17 | MAJOR. Добавлен дисквалификатор о классе защищаемых данных, рассекаемом планируемым разрезом. На гринфилде он особенно дёшев: классы существуют пока только в требованиях, и стянуть их в одну границу ничего не стоит — в отличие от той же операции после запуска. Старым ADR: перепроверять нечего — ни одного ADR по этому документу не существует (проверено по полю «Метод» всех пятнадцати ADR набора 2026-09-21). Указание «проверить, где по плану окажутся защищаемые данные» адресовано первому применению, а не прошлому |
| 2.0 | 2026-09-17 | MAJOR, по итогам прогона E-02 и разбора глав 6–7 Форда и Ричардса. Добавлен дисквалификатор об архитектурном кванте: разные цели по доступности внутри одного кванта недостижимы с первого дня. Добавлены силы интеграции в объёме, измеримом без истории: транзакции (дисквалификатор), рабочий процесс (по прогнозу), общий код (неизмерим — не заполнять), отношения в данных (не факт, а наше решение). Старым ADR: перепроверять нечего — ADR по этому документу не существует. Указание «проверить, не нарисованы ли границы поверх одной базы при разных целях по доступности» адресовано первому применению |
| 1.0 | 2026-09-16 | Первая версия. Выделена из D-02 v2.1 по итогам прогона E-01: на системе без истории изменений раздел 1 D-02 неприменим, и вопрос там другой — не «где резать», а «какие границы заложить». Пять вопросов, пять осей вместо восьми (три неизмеримы без истории), пометка [прогноз], таблица применимости форм разреза |