System Design Space
Граф знанийНастройки

Обновлено: 24 июня 2026 г. в 20:21

Introducing Domain-Oriented Microservice Architecture

средний

Разбор статьи Uber Engineering (2020): эволюция от монолита к DOMA, доменные границы, слои зависимостей, шлюзы домена, точки расширения и управляемость на масштабе Uber.

Доменно-ориентированная микросервисная архитектура ценна тем, что ставит бизнес-границы выше сетевых схем и диаграмм вызовов.

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

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

Практическая польза главы

Практика проектирования

Связывайте доменные границы, слои зависимостей и зоны ответственности команд.

Качество решений

Согласовывайте контракты шлюза домена, точки расширения и платформенные API.

Аргументация на интервью

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

Анализ отказов

Контролируйте риск организационной связанности и узкие места у команд общей платформы.

Источник

Uber Engineering, 2020

Оригинальная статья Adam Gluck о редизайне архитектуры Uber и переходе к DOMA.

Открыть источник

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

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

Эволюция архитектуры Uber

2012-2013

Монолитная архитектура

У Uber было два крупных сервиса. Пока команда росла от десятков к сотням инженеров, монолит держался; дальше начали расти риски доступности, сложность деплоев и стоимость каждого изменения.

  • Падение крупного компонента задевало большую часть продукта — риск доступности концентрировался в одной точке.
  • Одно изменение могло затронуть слишком много продукта сразу: релизы становились опасными.
  • Слабое разделение ответственности между .
  • Изменения в бизнес-логике внедрялись медленно.
2014-2017

Переход к микросервисам

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

  • Зависимостей между сервисами стало столько, что схему связей уже никто не держал в голове.
  • Причину инцидента приходилось трассировать через десятки команд — расследование растягивалось.
  • Границы ответственности и модели данных размывались, и спор «чей это сервис» возникал на каждом шаге.
  • Когнитивная нагрузка на разработчика росла: чтобы что-то поменять, надо было понимать слишком многое.
2018+

DOMA (Domain-Oriented Microservice Architecture)

Uber перестал смотреть на систему как на тысячи отдельных сервисов и переосмыслил её как одно большое распределённое приложение, к которому применимы привычные архитектурные принципы: , слои, контракты и расширяемость.

  • Единицей дизайна становится домен, а не отдельный сервис — решения принимаются крупнее.
  • Зависимости становятся управляемыми через .
  • Внешние интеграции идут через .
  • Кросс-доменные интеграции проходят через , а не через прямую связность.

Принципы DOMA

Дизайн вокруг доменов, а не отдельных сервисов

Единица проектирования здесь — , которая закрывает доменную задачу целиком, а не один сервис. Так достаётся одной команде, и планировать изменения проще: понятно, кого спрашивать.

Домены группируются в слои

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

У домена есть явный входной контракт

Снаружи в домен ведёт ровно одна дверь — . Он держит внешний стабильным, поэтому внутреннюю реализацию можно переписывать, не предупреждая потребителей.

Прямых кросс-доменных зависимостей нет

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

Слои DOMA в Uber

СлойНазначениеПримеры
Инфраструктурный слойБазовые , нужные любой инженерной организации: хранение, сеть, наблюдаемость и инфраструктурная идентификация.API хранения, сетевые примитивы, инфраструктурная идентификация, инструменты среды выполнения
Бизнес-слойОбщие бизнес-возможности Uber, не привязанные к одному вроде Rides, Eats или Freight.Платёжные политики, сигналы антифрода, пользовательские профили
Продуктовый слойЛогика конкретной , но без привязки к одному клиентскому приложению.Жизненный цикл заказа поездки, правила диспетчеризации, логика доступности водителей
Слой представленияФункциональность, привязанная к пользовательским интерфейсам: мобильному приложению или вебу.Сценарии экранов заказа, координация действий из интерфейса, правила UX для конкретного приложения
Пограничный слойБезопасная экспозиция API наружу и адаптация под особенности клиентских приложений.Пограничные шлюзы, политики авторизации, композиция API, адаптация запросов

Базовое правило: сервисы верхнего слоя зависят только от сервисов нижележащих слоев.

Контракты

Паттерны межсервисной коммуникации

Шлюз домена и точки расширения держатся на контрактах между командами: размыт контракт — размыта и граница домена.

Открыть главу

Шлюз домена и точки расширения

Расширение логики через плагины

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

Расширение модели данных через необязательные поля

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

Локальные точки расширения команд

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

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

Что получилось на выходе

  • Вместо 2200 сервисов как плоского списка — примерно 70 доменов как управляемых единиц; на этом уровне систему уже можно держать в голове.
  • Зависимости стали предсказуемыми: слоистая архитектура и строгое не дают связям расти в любую сторону.
  • Стабильные контракты шлюза домена развязали релизы: домены мигрируют и выкатываются независимо, не дожидаясь соседей.
  • Разработчику нужно понимать меньше, а причину инцидента видно быстрее — обе цены масштаба пошли вниз.

Когда выбирать монолит, микросервисы и DOMA

Размер организацииБазовый выборПочему
СтартапМонолит или Главное — проверить рынок дёшево и быстро; операционная сложность сервисной архитектуры здесь только мешает.
Средняя компанияКлассические микросервисыНесколько команд уже мешают друг другу в одном кодовом базе — нужна независимая поставка и изоляция технологических рисков по подсистемам.
Крупная организацияDOMA-подходТысячи инженеров уже не помещаются в плоскую сетку сервисов: нужны доменные границы, масштабируемое и системная связанность, которую кто-то целенаправленно удерживает в рамках.

Типичные ошибки при внедрении DOMA

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

Шлюз домена как тонкая прослойка без контракта, и соглашения об уровне сервиса (SLA): такой шлюз ничего не стабилизирует и ломает потребителей при первом же изменении.

Сохранить или между доменами и назвать это DOMA — на схеме границы есть, в данных их нет.

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

Источники

Связанные главы

  • Зачем нужны микросервисы и интеграция - Контекст для выбора сервисных границ и интеграционных подходов до внедрения доменно-ориентированной модели.
  • Стратегии декомпозиции - Как выделять ограниченные контексты и поэтапно снижать связность, не теряя управляемость по дороге — то, с чего начинается любой переход к доменам.
  • Learning Domain-Driven Design (short summary) - DDD-основа для формирования доменов, ответственности команд и контрактов, на которых строится DOMA.
  • Паттерны межсервисной коммуникации - Подходы к синхронному и асинхронному взаимодействию, которые стабилизируют контракты шлюза домена и кросс-доменные интеграции.
  • Обнаружение сервисов (service discovery) - Инфраструктурный слой обнаружения сервисов для масштабируемого взаимодействия доменных компонентов.
  • Monolith to Microservices (short summary) - Пошаговый план перехода от монолита к сервисной архитектуре с контролем рисков и связности.
  • Uber/Lyft - Компания, на чьём масштабе доменная декомпозиция и архитектурное управление перестают быть теорией и становятся условием выживания системы.

Чтобы отмечать прохождение, включи трекинг в Настройки