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

Обновлено: 5 марта 2026 г. в 21:19

Introducing Domain-Oriented Microservice Architecture

mid

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

Primary source

Uber Engineering, 2020

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

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

DOMA (Domain-Oriented Microservice Architecture) - подход Uber к управлению очень большой микросервисной экосистемой. Ключевая идея: проектировать не набор изолированных сервисов, а домен-ориентированные коллекции сервисов со строгими контрактами, слоями зависимостей и точками расширения.

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

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

2012-2013

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

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

  • Риски доступности: падение крупного компонента влияло на большую часть продукта.
  • Опасные деплои: большие релизы с высоким blast radius.
  • Слабая separation of concerns между бизнес-возможностями.
  • Медленный execution изменений в бизнес-логике.
2014-2017

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

Ставка на надежность, ownership и скорость разработки сначала сработала. Но при росте до тысяч инженеров появился distributed monolith с избыточными связями.

  • Чрезмерное число межсервисных зависимостей.
  • Сложная трассировка причин инцидентов через много команд.
  • Неочевидные границы ответственности и моделей данных.
  • Рост когнитивной нагрузки для разработчиков.
2018+

DOMA (Domain-Oriented Microservice Architecture)

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

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

Принципы DOMA

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

Ключевая единица проектирования - коллекция сервисов, которая решает доменную задачу end-to-end. Это упрощает ownership и roadmap изменений.

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

Сервисы верхнего уровня могут зависеть только от нижнего. Такой dependency rule ограничивает циклы зависимостей и уменьшает blast radius при изменениях.

У домена есть clean interface через gateway

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

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

Ни shared code, ни shared data model между доменами. Для кастомной интеграции используются контролируемые extension points.

Слои DOMA в Uber

СлойНазначениеПримеры
Infrastructure layerБазовые capability, нужные любой инженерной организации: storage, networking, observability, platform primitives.Storage APIs, network primitives, infra identity, runtime tooling
Business layerОбщие бизнес-возможности Uber, не привязанные к конкретной LOB (Rides/Eats/Freight).Платежные политики, fraud-сигналы, пользовательские профили
Product layerЛогика конкретной продуктовой линии, но без привязки к одному клиентскому приложению.Ride request lifecycle, dispatch policies, driver supply logic
Presentation layerФункциональность, привязанная к пользовательским интерфейсам (mobile/web).Флоу экрана заказа, UI-driven orchestration, app-specific UX rules
Edge layerБезопасная экспозиция API наружу и адаптация под особенности клиентских приложений.Edge gateways, auth policies, API composition, request shaping

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

Контракты

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

Gateway и extension points работают только при явных, стабильных контрактах между командами.

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

Gateway и точки расширения

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

Сервисы внутри домена предоставляют plugin interfaces. Команды подключают дополнительную доменную проверку без форка базовой логики.

Расширение модели данных через optional fields

К core-модели добавляются доменно-специфичные атрибуты, чтобы не создавать прямую связь между доменами на уровне общей схемы.

Локальные extension points команд

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

Практический эффект gateway: домен может мигрировать внутренние сервисы, не ломая потребителей, пока внешний контракт остается стабильным.

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

  • Снижение сложности за счет перехода от 2200 сервисов к ~70 доменам как управляемым единицам.
  • Более предсказуемые зависимости благодаря layered design и строгому dependency direction.
  • Более простые миграции и независимые релизы доменов через стабильные gateway-контракты.
  • Снижение когнитивной нагрузки разработчиков и ускорение локализации инцидентов.

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

Размер организацииБазовый выборПочему
СтартапМонолит / modular monolithМинимальная операционная сложность, быстрый product-market fit, низкая цена изменений.
Средняя компанияКлассические микросервисыНужна независимая поставка несколькими командами и контроль технологических рисков по подсистемам.
Крупная организацияDOMA-подходНужна управляемость тысяч инженеров, доменные границы, масштабируемый governance и снижение системной связности.

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

Называть доменом любой набор случайных сервисов без явной бизнес-границы и ownership-модели.

Делать gateway тонким proxy без контракта, versioning и SLA между доменами.

Оставлять shared database/shared schema между доменами и называть это «DOMA».

Строить слои формально, но нарушать правило зависимостей (верхние слои ходят в peers/верх).

Связанные материалы

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

System Design Space

© 2026 Александр Поломодов