Software · Arquitetura de Software
Arquitetura de Microsserviços: Decomposição por Domínio, Autonomia e Resiliência
Como estruturar microsserviços autônomos por Bounded Contexts, gerenciar persistência isolada e balancear a complexidade distribuída com API Gateways.
Neste artigo
A Arquitetura de Microsserviços estrutura um sistema como um conjunto de serviços autônomos, de granularidade fina e fracamente acoplados, em que cada unidade responde por uma única capacidade de negócio delimitada por um Bounded Context. Diferente do desenvolvimento em monólitos tradicionais, onde toda a base de código é compilada e implantada de forma monolítica, os microsserviços possuem ciclos de vida de compilação, teste e implantação completamente independentes.
Essa independência viabiliza times autônomos trabalhando em paralelo e permite escalar recursos de computação cirurgicamente: se o módulo de pagamentos enfrenta picos de demanda durante uma promoção, apenas as instâncias de pagamento são escaladas horizontalmente, sem necessidade de multiplicar os recursos dedicados ao catálogo ou à emissão de relatórios.
Pilares Arquiteturais dos Microsserviços
Para colher os benefícios reais desse modelo sem transformá-lo em um emaranhado caótico de dependências de rede, quatro princípios devem ser rigorosamente observados:
graph TD
Clients["<b>Clientes Web / Mobile</b>"] --> GW["<b>API Gateway</b><br/>(Auth, Rate Limit, Agregação)"]
GW -->|gRPC / HTTP| S_Ped["<b>Serviço Pedidos</b>"]
GW -->|gRPC / HTTP| S_Est["<b>Serviço Estoque</b>"]
GW -->|gRPC / HTTP| S_Usu["<b>Serviço Usuário</b>"]
S_Ped --> DB1[("DB Pedidos")]
S_Est --> DB2[("DB Estoque")]
S_Usu --> DB3[("DB Usuários")]
S_Ped -.->|Publica Eventos| Kafka[["Barramento de Eventos (Kafka)"]]
S_Est -.->|Publica Eventos| Kafka
S_Usu -.->|Publica Eventos| Kafka
classDef client fill:#0f172a,stroke:#64748b,stroke-width:1px,color:#f8fafc;
classDef gateway fill:#132338,stroke:#38bdf8,stroke-width:2px,color:#f8fafc;
classDef svc fill:#1e293b,stroke:#4ade80,stroke-width:1px,color:#f8fafc;
classDef db fill:#1e1b4b,stroke:#a855f7,stroke-width:1px,color:#f8fafc;
classDef bus fill:#0f2724,stroke:#34d399,stroke-width:2px,color:#f8fafc;
class Clients client;
class GW gateway;
class S_Ped,S_Est,S_Usu svc;
class DB1,DB2,DB3 db;
class Kafka bus;
1. Banco de Dados Isolado por Serviço (Database per Service)
Cada microsserviço deve gerenciar sua própria base de persistência. O compartilhamento de um banco de dados relacional centralizado entre múltiplos serviços representa o anti-padrão mais comum do mercado, pois recria o acoplamento monolítico na camada de dados: qualquer migração de coluna ou bloqueio de tabela (table lock) derruba serviços adjacentes. Se o Serviço de Pedidos necessita de dados de clientes, ele consulta a API pública do Serviço de Usuários ou assina eventos de sincronização, nunca executando junções SQL diretas nas tabelas alheias.
2. Protocolos de Comunicação Inteligentes e Simples
A integração opera sob a filosofia de dumb pipes, smart endpoints (canais simples com lógica nas pontas). Para chamadas síncronas de baixa latência entre serviços internos, utilizam-se contratos fortemente tipados em gRPC ou interfaces RESTful; para desacoplamento temporal e propagação de mudanças de estado, adotam-se corretores assíncronos como Kafka ou RabbitMQ.
3. Autonomia de Implantação e Contêineres
Os serviços são empacotados em contêineres imutáveis (Docker) contendo suas próprias dependências de runtime e orquestrados em plataformas elásticas como Kubernetes. Uma falha ou atualização no serviço de notificações não interrompe a esteira do serviço de checkout.
4. O Papel do API Gateway
Expor dezenas de microsserviços diretamente aos navegadores e celulares expõe a arquitetura interna e cria complexidade na gestão de segurança. O padrão API Gateway estabelece um ponto único de entrada que centraliza:
- Roteamento Dinâmico: Encaminha chamadas com base em prefixos de rota para os nós internos corretos.
- Autenticação e Autorização: Valida tokens JWT antes que a requisição atinja a rede privada dos serviços.
- Agregação de Respostas: Consolida dados de diferentes serviços em uma única resposta compacta para dispositivos móveis, reduzindo o número de viagens de ida e volta pela internet (round-trips).
- Controle de Vazão (Rate Limiting): Protege os serviços internos contra sobrecargas repentinas ou ataques automatizados.
Comparativo: Microsserviços versus SOA Tradicional
É frequente a comparação entre microsserviços e a Arquitetura Orientada a Serviços (SOA) corporativa dos anos 2000, contudo suas premissas de engenharia divergem frontalmente:
| Dimensão | Microsserviços | SOA Corporativa Tradicional |
|---|---|---|
| Granularidade | Fina: orientada a contextos delimitados específicos. | Grossa: serviços amplos cobrindo divisões corporativas inteiras. |
| Barramento | Fios simples (dumb pipes) como filas de mensagens enxutas. | Barramento corporativo pesado (ESB) contendo regras de negócio e transformações XML. |
| Persistência | Descentralizada: banco dedicado por serviço (poliglotismo). | Centralizada: banco de dados corporativo compartilhado. |
| Governança | Descentralizada: equipes escolhem suas linguagens e ferramentas. | Centralizada: comitês rígidos e padrões padronizados para toda a empresa. |
Os Custos e Desafios Reais da Distribuição
Embora ofereçam autonomia e escala técnica, os microsserviços cobram um preço operacional elevado que não deve ser subestimado:
- Falácias da Computação Distribuída: A rede não é confiável nem instantânea. Toda chamada entre serviços pode sofrer lentidão ou perda de pacotes, exigindo padrões de resiliência como Circuit Breaker, Retries exponenciais com jitter e Timeouts rigorosos.
- Consistência e Transações: Transações ACID clássicas não existem entre serviços independentes. A atomicidade de processos que envolvem múltiplos contextos exige o padrão Saga (orquestrado ou coreografado) com transações compensatórias em caso de falha no meio do caminho.
- Observabilidade Contínua: Diagnosticar um erro exige rastreamento distribuído ponta a ponta (OpenTelemetry), agregação centralizada de logs e métricas de latência p99 por rota.
Por esses motivos, a recomendação prática predominante na indústria para equipes em fase inicial é começar com um Monólito Modular bem delimitado: as fronteiras de domínio são construídas no código desde o primeiro dia, preservando a facilidade operacional até que o volume de transações ou a escala organizacional realmente exijam a divisão física em microsserviços.