Pular para o conteúdo
fernando.moretes.com
BlogEstudosCursosE-booksOpen SourcePodcasts
Loading…
Fernando Azevedo

Arquiteto de TI Especialista

Arquitetura, AWS, IA em produção, sistemas financeiros e FinOps, escritos a partir do que foi operado, com os números.

  • LinkedIn
  • GitHub
  • E-mail

Conteúdo

  • Blog
  • Estudos de arquitetura
  • Cursos
  • E-books
  • Open Source
  • Podcasts
  • Assuntos
  • Trilhas

Ferramentas

  • Well-Architected self-check
  • Arquitetura deste site
  • Números públicos
  • Histórico de estudo

Sobre

  • Comunidade
  • IA Builder
  • Perfil
  • Currículo (CV)
  • Trabalhe comigo
  • Media kit
  • RSS do blog
  • RSS dos estudos
  • Artigos narrados (podcast)
  • llms.txt
  • Termos, privacidade e uso de IA

(c) 2026 Fernando Francisco Azevedo

Estudos/Teardown
RSSMarkdownLLMs
TeardownUberMicrosserviços

Uber DOMA: Como Camadas de Domínio Domaram a Explosão de Microsserviços

23 de jul. de 2020 7 min Com apoio de IA000 visualizações00 reproduções
Ouvir estudo

cerca de 7 min · áudio gerado ao tocar

Microsserviços prometem autonomia e velocidade. Na prática, sem disciplina estrutural, entregam um grafo de dependências caótico que nenhum engenheiro consegue raciocinar completamente. A Uber chegou a 2.200+ serviços e precisou inventar uma nova camada de organização, não para os computadores, mas para os times.

Ficha Técnica

Empresa
Uber Technologies
Domínio
Mobilidade urbana, entregas, logística
Escala de serviços (pré-DOMA)
~2.200 microsserviços ativos
Publicação do artigo DOMA
Setembro de 2020
Stack principal
Go, Java, Python; gRPC; Kafka; Cadence (orquestração de workflows)
Rede de entrega
Multi-região, presença global, data centers próprios + nuvem híbrida
Problema central
Acoplamento cruzado incontrolável entre serviços sem fronteiras de domínio claras
Solução adotada
DOMA: Domain-Oriented Microservice Architecture com camadas, gateways e extensões

O Problema: Quando Microsserviços Viram um Monólito Distribuído

A Uber cresceu de um monólito Python para uma arquitetura de microsserviços ao longo de vários anos, impulsionada pela necessidade de escalar times independentes em múltiplos produtos: Rides, Eats, Freight, ATG. O resultado natural desse crescimento foi uma explosão de serviços: cada time criava o que precisava, quando precisava, sem uma visão global das dependências.

O sintoma mais visível era o que o time de engenharia chamou internamente de dependency hell: um serviço de pagamento chamando diretamente um serviço de mapeamento de rotas; um serviço de notificações acoplado a lógica de precificação; ciclos de dependência que tornavam deployments simples em eventos de coordenação complexos. Com 2.200+ serviços, nenhum engenheiro individual conseguia ter um mapa mental confiável do sistema.

O problema não era técnico na raiz, era organizacional. Conway's Law operando em escala máxima: a arquitetura do sistema espelhava a estrutura de comunicação dos times, que por sua vez era caótica porque cresceu organicamente sem uma taxonomia de responsabilidades. A solução precisava atacar os dois lados: estrutura técnica e estrutura organizacional simultaneamente.

Além do acoplamento, havia um problema de descoberta e reuso. Times criavam serviços duplicados porque não sabiam que a funcionalidade já existia em outro lugar. A ausência de um contrato explícito entre serviços significava que qualquer mudança interna podia, e frequentemente causava, quebras em cascata em consumidores que nunca deveriam ter acesso direto àquela implementação.

Arquitetura DOMA Reconstruída

Visão em camadas da organização de domínios na Uber. Cada domínio expõe uma Layer Interface (gateway) e pode conter sub-domínios. Serviços internos são opacos para consumidores externos ao domínio. Extensões permitem customização sem modificar o núcleo.

🌐 Clients & Edge
  • Mobile App · iOS / Android
  • Partner API · External Consumers
🚪 API Gateway Layer
  • API Gateway · Auth / Rate Limit / Routing
🏗️ Domain: Rides
  • Rides Layer Interface · (Domain Gateway)
  • Dispatch Service · (internal)
  • Driver Matching · (internal)
  • Rides Extension · (customization hook)
💳 Domain: Payments
  • Payments Layer Interface · (Domain Gateway)
  • Billing Service · (internal)
  • Fraud Detection · (internal)
🗺️ Domain: Maps & ETA
  • Maps Layer Interface · (Domain Gateway)
  • Routing Engine · (internal)
  • ETA Prediction · (internal)
📦 Shared Platform Layer
  • Observability Platform · Metrics / Tracing / Logs
  • Kafka · Event Bus
  • Cadence · Workflow Orchestration
🗄️ Storage Layer (per domain)
  • Rides DB · (Schemaless / MySQL)
  • Payments DB · (isolated)
  • Maps Cache · (Redis / in-memory)

Como o DOMA Funciona: Domínios, Camadas e Contratos

O DOMA introduz quatro conceitos centrais que, em conjunto, reconstroem a ordem em um ecossistema de microsserviços caótico.

1. Domínios (Domains): Um domínio é uma coleção de microsserviços que representam uma área de negócio coesa: Rides, Payments, Maps, Driver, etc. A granularidade não é arbitrária: segue as linhas de responsabilidade dos times (Conway's Law deliberadamente aplicada, não acidental). Cada domínio tem um owner claro, um roadmap independente e uma fronteira de responsabilidade explícita.

2. Camadas (Layers): Domínios são organizados em camadas hierárquicas. Camadas inferiores (plataforma, infraestrutura) não podem depender de camadas superiores (produto, experiência). Essa restrição unidirecional é a chave para eliminar ciclos de dependência. Na prática, a Uber definiu camadas como: Infrastructure → Platform → Business Domain → Product → Experience. Um serviço de Maps não pode depender de lógica de Rides; um serviço de Rides pode depender de Maps.

3. Layer Interface (Gateway de Domínio): Cada domínio expõe exatamente uma interface pública, o Layer Interface. Serviços internos ao domínio são completamente opacos para o mundo externo. Consumidores externos só podem interagir com o domínio através dessa interface, que funciona como um API Gateway interno. Isso cria um contrato estável: o domínio pode refatorar sua implementação interna livremente, desde que mantenha a interface.

4. Extensões (Extensions): Extensões são o mecanismo de customização sem modificação. Em vez de um consumidor fazer fork de um serviço ou adicionar lógica condicional no núcleo ("se produto X, então..."), ele registra uma extensão que é invocada em pontos específicos do fluxo do domínio. É essencialmente o padrão Strategy/Plugin aplicado em escala de plataforma. Isso foi crítico para a Uber porque produtos diferentes (Rides vs. Eats vs. Freight) precisam de comportamentos ligeiramente diferentes nos mesmos domínios base.

A combinação desses quatro elementos cria o que o artigo da Uber chama de "structured modularity", modularidade com regras de composição explícitas, não apenas decomposição arbitrária. O resultado prático é que o grafo de dependências, antes um espaguete, passa a ter uma topologia de DAG (Directed Acyclic Graph) com camadas bem definidas.

A Dimensão Organizacional: Por Que Isso É Tanto um Problema de Times Quanto de Código

Um aspecto que o artigo da Uber trata com seriedade e que muitas análises superficiais ignoram: DOMA não é apenas uma reorganização de código. É uma reorganização de responsabilidades e poder de decisão.

Antes do DOMA, qualquer time podia criar dependências em qualquer serviço. Isso parece democrático, mas na prática significava que ninguém era responsável por nada de forma abrangente. O time de Payments não podia refatorar seu serviço de billing sem coordenar com 40 consumidores diretos que tinham acoplamento com detalhes de implementação interna.

Com DOMA, o Layer Interface cria uma fronteira de propriedade clara. O time dono do domínio é o único árbitro de quais funcionalidades são expostas publicamente. Isso tem consequências políticas reais: times de produto que antes podiam "pular a fila" acessando serviços internos diretamente agora precisam negociar adições à interface pública com o time dono. Isso é atrito intencional, o tipo de atrito que força conversas sobre design em vez de gambiarra.

O mecanismo de extensões é particularmente inteligente do ponto de vista organizacional. Ele resolve o problema clássico de plataformas: como um serviço central atende às necessidades divergentes de múltiplos produtos sem se tornar um gargalo ou um acumulador de lógica condicional? A resposta do DOMA é inverter o controle, o domínio define os pontos de extensão, os produtos registram seus comportamentos específicos. O time de plataforma não precisa conhecer todos os casos de uso; os times de produto não precisam de acesso ao núcleo.

Isso também tem implicações para hiring e onboarding. Um engenheiro novo no time de Payments precisa entender apenas o domínio de Payments e suas interfaces com domínios adjacentes, não o sistema inteiro. A complexidade cognitiva é delimitada pela fronteira do domínio. Em um sistema com 2.200 serviços sem essa estrutura, o onboarding efetivo levava meses; com DOMA, o escopo de aprendizado inicial é drasticamente reduzido.

Matriz de Decisões: Alternativas Consideradas

DOMA (abordagem adotada)

Prós
  • Preserva autonomia dos times dentro do domínio
  • Contratos explícitos via Layer Interface reduzem acoplamento acidental
  • Extensões permitem customização sem modificar núcleo
  • Compatível com migração incremental, não exige big bang
Contras
  • Overhead de governança: quem decide as fronteiras dos domínios?
  • Layer Interface pode virar gargalo de latência se mal implementado
  • Extensões mal gerenciadas recriam o problema de acoplamento em outro nível

Melhor equilíbrio para a escala e maturidade organizacional da Uber

Consolidação em Monólito Modular

Prós
  • Elimina latência de rede entre serviços do mesmo domínio
  • Transações ACID dentro do módulo sem coordenação distribuída
Contras
  • Inviável para a escala de times da Uber, conflitos de merge, deploys acoplados
  • Perde os benefícios de isolamento de falha já conquistados
  • Migração de 2.200 serviços para monólito é risco inaceitável

Rejeitado, retrogredir não resolve o problema organizacional

Service Mesh Puro (Istio/Envoy) sem reorganização de domínios

Prós
  • Melhora observabilidade e controle de tráfego sem mudança de código
  • Aplica políticas de segurança (mTLS) de forma transparente
Contras
  • Não resolve o problema de acoplamento lógico, apenas adiciona visibilidade a ele
  • Não endereça a questão de ownership e responsabilidade de times

Complementar, não substituto, necessário mas insuficiente sozinho

API Management Centralizado (estilo ESB)

Prós
  • Controle centralizado de contratos e versioning
Contras
  • Recria o gargalo do ESB, ponto único de falha e bottleneck de deploy
  • Vai contra a filosofia de autonomia de times que a Uber já havia conquistado
  • Não escala com 2.200 serviços sem fragmentação do próprio ESB

Rejeitado, antipadrão conhecido para essa escala

Leitura pelos Pilares Well-Architected

Segurança

Positivo: A Layer Interface como único ponto de entrada do domínio cria um perímetro natural para aplicar autenticação, autorização e auditoria. Serviços internos ficam inacessíveis diretamente, reduzindo a superfície de ataque. Gap identificado: O artigo não detalha o modelo de autorização entre domínios, em sistemas financeiros, precisaria de controle explícito de quais domínios podem chamar quais interfaces, com auditoria de cada chamada cross-domain. A Uber provavelmente resolve isso via seu service mesh (Envoy + mTLS + RBAC), mas a integração com DOMA não é documentada publicamen

Confiabilidade

Positivo: O isolamento por domínio limita o blast radius de falhas. Uma degradação no domínio de Maps não propaga diretamente para Payments. As extensões, se implementadas com circuit breakers, permitem que o fluxo principal continue mesmo quando uma customização falha. Gap: O Layer Interface introduz um hop adicional em cada chamada cross-domain. Se não for implementado com caching adequado e circuit breakers, pode virar um ponto de falha concentrado. A Uber usa Cadence para workflows de longa duração, o que mitiga falhas transientes, mas a resiliência do próprio gateway de domínio pr

Eficiência de performance

Trade-off explícito: DOMA adiciona latência em chamadas cross-domain ao forçar o roteamento pelo Layer Interface em vez de chamadas diretas ponto-a-ponto. Para a Uber, onde latência de matching de motoristas é crítica (centenas de milissegundos fazem diferença na experiência), isso é um custo real. O artigo não quantifica esse overhead. Minha estimativa conservadora é 1-5ms por hop adicional em uma infraestrutura bem otimizada, aceitável para a maioria dos fluxos, mas potencialmente significativo em caminhos críticos com múltiplos saltos de domínio.

Otimização de custos

Positivo: Melhor reuso de serviços reduz duplicação, times param de recriar funcionalidades que já existem em outros domínios. Negativo: O Layer Interface de cada domínio precisa ser um serviço de alta disponibilidade, o que significa redundância, monitoramento e manutenção adicionais. Com dezenas de domínios, isso é um custo operacional não trivial. A Uber tem escala para absorver isso; empresas menores precisariam avaliar se o overhead de infraestrutura compensa os ganhos de organização.

Sustentabilidade

O reuso de serviços via Layer Interface reduz a proliferação de instâncias redundantes, o que tem impacto positivo em consumo de recursos computacionais. Menos duplicação de código significa menos superfície de manutenção e menor probabilidade de manter serviços zumbi ativos desnecessariamente. Não há dados públicos sobre o impacto de DOMA em eficiência de recursos na Uber.

FA
O Que Eu Faria Diferente
Arquiteto de TI Especialista

DOMA é uma das contribuições mais honestas e práticas que já vi publicadas sobre arquitetura de microsserviços em escala. Não é teoria, é uma solução que emergiu de dor real. Mas há três pontos onde eu divergiria ou complementaria. 1. Contratos como artefatos de primeira classe, não como convenção. O Layer Interface é uma ideia poderosa, mas o artigo da Uber não detalha como os contratos são versionados, testados e evoluídos. Em sistemas financeiros onde trabalhei, a ausência de contract testing explícito (Pact, Protolock para gRPC) significa que "a interface não mudou" é uma promessa baseada em disciplina humana, não em enforcement automatizado. Eu adicionaria contract testing como gate obrigatório no CI/CD de qualquer mudança em um Layer Interface. 2. O modelo de extensões precisa de um registro centralizado com visibilidade. Extensões resolvem o problema de customização, mas criam um novo problema de descoberta: quais extensões estão registradas em qual domínio? Quem as possui? Em um sistema com dezenas de domínios e centenas de extensões, isso vira um grafo de dependências de segundo nível. Eu implementaria um registry de extensões com ownership explícito, SLOs e alertas de extensões órfãs. 3. A dimensão de segurança precisa ser cidadã de primeira classe no modelo. DOMA define fronteiras organizacionais e técnicas, mas não define fronteiras de segurança explicitamente.

Lições Transferíveis: O Que Qualquer Organização Pode Aprender

DOMA é frequentemente descartado como "coisa de Uber", uma solução para uma escala que a maioria das empresas nunca atingirá. Essa leitura é equivocada. Os princípios são aplicáveis muito antes de você ter 2.200 serviços.

A explosão de microsserviços começa cedo. Na minha experiência, times de 30-50 engenheiros já sofrem com os sintomas que o DOMA resolve: dependências cruzadas não documentadas, duplicação de funcionalidades, onboarding lento. Você não precisa esperar 2.000 serviços para introduzir fronteiras de domínio.

Comece com o mapa de dependências, não com a reorganização. Antes de qualquer mudança estrutural, torne visível o que existe. Ferramentas como Backstage (CNCF) ou até um grafo simples gerado a partir dos logs do service mesh revelam os padrões de acoplamento. O mapa é o diagnóstico; DOMA é um tratamento possível.

O Layer Interface é aplicável mesmo sem microsserviços. Em monólitos modulares, o mesmo princípio se aplica: módulos expõem interfaces públicas explícitas, implementações internas são privadas. A diferença é que a fronteira é de pacote/módulo em vez de rede. O padrão é agnóstico ao estilo de deployment.

Extensões são o padrão correto para plataformas internas. Qualquer time que constrói uma plataforma interna enfrenta o dilema: ser genérico demais (inútil) ou específico demais (não reutilizável). O modelo de extensões do DOMA, define os pontos de variação, deixa os consumidores injetarem o comportamento, é a resposta correta para esse dilema e se aplica independentemente da escala.

Veredicto

DOMA é uma das contribuições arquiteturais mais substanciais publicadas por uma empresa de tecnologia na última década, não porque seja revolucionária em teoria, mas porque é uma solução honesta e documentada para um problema que a maioria das organizações enfrenta e poucos resolvem de forma sistemática. A combinação de domínios, camadas, Layer Interface e extensões não é apenas uma reorganização técnica: é um framework de governança que alinha estrutura de código, estrutura de times e estrutura de responsabilidades. Os pontos fracos são reais: overhead de latência nos gateways de domínio, risco de que extensões mal gerenciadas recriem o problema original em outro nível, e ausência de um modelo de segurança explícito integrado ao framework. Mas esses são problemas de implementação, não falhas de design. O que mais me impressiona no DOMA é o reconhecimento explícito de que arquitetura de software é inseparável de design organizacional. Não há solução técnica para um problema de Conway's Law que não passe também por uma mudança na estrutura de ownership e comunicação dos times. A Uber entendeu isso e construiu uma solução que ataca os dois lados.

Referências

Uber Engineering: Microservice Architecture (DOMA)Martin Fowler: Conway's LawCNCF Backstage: Service CatalogUber: Cadence Workflow OrchestrationAWS Well-Architected FrameworkSam Newman: Building Microservices (2nd ed.)Pact: Consumer-Driven Contract Testing
#microservices#domain-driven-design#uber#platform-engineering#architecture#scalability#organizational-design#api-gateway
Fontes do caso
Uber: Microservice Architecture (DOMA)
Compartilhar:LinkedInWhatsAppXBaixar em Markdown
Escrito com apoio de IA a partir do caso público e da minha leitura como arquiteto.
Próximo passo
Trilha Arquiteto de IA, gratuitaFundamentos, LLMs, RAG, tools, MCP e arquitetura na AWS, em aulas curtas e interativas.Começar a trilhaAgentes de IA em produção na AWSComo eu desenho, oriento e audito agentes que vão ao ar, com os números e as fontes.Ver o IA Builder

Continue lendo

TeardownFigma: Sharding Horizontal de Postgres Sem Parar de CrescerEm 2022, o Figma enfrentou limites físicos do seu banco de dados Postgres monolítico e executou uma migração de sharding horizontal com particionamento por chave, roteamento dinâmico e migração incremental, tudo isso sem downtime e sem travar o crescimento do produto. Este teardown reconstrói a arquitetura, analisa as decisões técnicas e aponta o que eu faria diferente.Ler TeardownNotion: O Modelo de Blocos e o Sharding do PostgresO Notion cresceu de um banco Postgres monolítico para uma arquitetura shardada horizontalmente, particionando dados por tenant para sustentar crescimento explosivo durante a pandemia. Este teardown reconstrói as decisões de modelagem, o processo de migração e os trade-offs reais de operar Postgres em escala.Ler TeardownNetflix: Chaos Engineering e Resiliência por DesignUma reconstrução arquitetural de como a Netflix transformou falhas inevitáveis em prática deliberada, da Simian Army ao failover regional automatizado. Este teardown examina as decisões técnicas, os trade-offs reais e o que separa resiliência de verdade de alta disponibilidade cosmética.Ler
AnteriorCloudflare 2019: O Regex que Derrubou uma Rede GlobalPróximoAWS Kinesis us-east-1 (2020): Quando um Limite de Threads do SO Derrubou Metade da AWS
Gostou deste estudo? Receba o próximo.

Post-mortems, ADRs e deep dives de arquitetura no seu email, do jeito que um arquiteto lê.

Sem spam · cancele quando quiser

Pergunte ao Fernando sobre isto

Uma resposta focada sobre este estudo, do meu assistente de IA, baseada no meu trabalho.

Participe da conversa

Entre para comentar

Confirme seu e-mail para participar, você também recebe a newsletter. Sem senha.

Neste estudo
O Problema: Quando Microsserviços Viram um Monólito DistribuídoArquiteturaComo o DOMA Funciona: Domínios, Camadas e ContratosA Dimensão Organizacional: Por Que Isso É Tanto um Problema de Times Quanto de CódigoMatriz de Decisões: Alternativas ConsideradasWell-ArchitectedLições Transferíveis: O Que Qualquer Organização Pode AprenderVeredictoReferências