- Aplicações com responsabilidades específicas
- Objetivos bem definidos e delimitados
- Fazem parte de um ecossistema distribuído
- São independentes e autônomos
- Se comunicam constantemente através de APIs e eventos
| Microserviços | Monolitos | |
|---|---|---|
| Domínio e responsabilidades | Objetivos específicos e bem definidos | Todos os contextos dentro da mesma aplicação |
| Tecnologias | Diversas linguagens e frameworks | Única stack tecnológica |
| Deploy e risco | Menor risco de falha geral | Alto risco de indisponibilidade total |
| Organização de equipes | Equipes especializadas por serviço | Todas as equipes no mesmo código |
| Projetos iniciais/POC | Complexidade inicial elevada | Implementação mais simples |
| Cenário | Microserviços | Monolito |
|---|---|---|
| Projetos onde o domínio é desconhecido | - | ✓ |
| Prova de conceito (POC) | - | ✓ |
| Governança tecnológica simplificada | - | ✓ |
| Facilidade na contratação e treinamento | - | ✓ |
| Centralização de código e recursos | - | ✓ |
| Compartilhamento de bibliotecas (Shared kernel) | - | ✓ |
| Escalabilidade de equipes | ✓ | - |
| Contextos de negócio bem definidos | ✓ | - |
| Maturidade em processos de entrega | ✓ | - |
| Equipes experientes | ✓ | - |
| Necessidade de escala independente | ✓ | - |
| Tecnologias específicas por contexto | ✓ | - |
- Identificar e separar contextos delimitados (Domain-Driven Design)
- Evitar granularidade excessiva dos serviços
- Analisar dependências para evitar monolito distribuído
- Planejar cuidadosamente a migração dos bancos de dados
- Aceitar duplicação controlada de dados
- Implementar comunicação baseada em eventos
- Adotar consistência eventual
- Estabelecer maturidade em CI/CD e testes automatizados
- Iniciar a migração pelas bordas do sistema
- Aplicar o padrão Strangler Fig
- Componentização via serviços independentes
- Organização orientada às áreas de negócio
- Smart endpoints and dumb pipes
- Mentalidade de produto, não projeto
- Projetado para tolerar falhas
- Governança descentralizada
- Gerenciamento descentralizado de dados
- Automação de infraestrutura
Todo sistema distribuído eventualmente falhará. Resiliência é um conjunto de estratégias implementadas intencionalmente para adaptar um sistema quando falhas ocorrem. Estratégias de resiliência minimizam riscos de perda de dados e transações críticas para o negócio.
- Sistemas devem adotar mecanismos de autopreservação para garantir operação com qualidade
- Evitar comportamento egoísta que sobrecarregue sistemas já comprometidos
- Um sistema lento pode ser pior que um sistema indisponível (efeito dominó)
- Monitoramento dos sinais vitais do sistema
- Sistemas não saudáveis podem se recuperar quando o tráfego é temporariamente redirecionado (self-healing)
- Implementação de health checks de qualidade:
- Passivo: Verificação externa da saúde do sistema
- Ativo: Auto-verificação do próprio sistema
- Proteção baseada na capacidade projetada do sistema
- Implementação de preferências programadas por tipo de cliente
- Proteção através da negação de requisições quando o sistema está comprometido
- Estados do circuito:
- Fechado: Requisições processadas normalmente
- Aberto: Requisições negadas imediatamente, retorno de erro instantâneo
- Meio-aberto: Quantidade limitada de requisições para verificar recuperação
- Filtragem de requisições inadequadas antes de chegarem ao sistema
- Implementação centralizada de políticas de Rate Limiting e Health Check
- Autenticação e autorização centralizadas
- Controle de tráfego de rede entre serviços
- Evita implementações de proteção em cada serviço individual
- Recursos incluem: mTLS, Circuit Breaker, Retry, Timeout, Fault Injection
- Prevenção de perda de dados em falhas
- Processamento em tempo próprio quando o servidor retorna online
- Compreensão profunda do message broker e sistemas de stream
- Implementação de políticas de retry com backoff exponencial
- Tratamento de situações complexas como falha do message broker
- Persistência de mensagens antes do envio para o message broker
- Remoção do registro após confirmação de recebimento
- Configuração de Auto Ack como false com commit manual
- Alinhamento de Prefetch com a volumetria esperada
- Tratamento adequado de duplicação de informações
- Definição clara de políticas de fallback
- Application Performance Monitoring (APM)
- Tracing distribuído
- Métricas e spans personalizados
- Implementação de OpenTelemetry
- API Composition: Agregação de dados através de Service Composer e API Gateway
- Decompose by business capability: Divisão por capacidades de negócio
- Strangler Fig Application: Migração gradual substituindo funcionalidades
- Anti-Corruption Layer (ACL): Camada de proteção entre contextos
- API Gateway: Ponto único de entrada para APIs
- Backend for Frontend (BFF): APIs específicas para diferentes frontends
- Transactional Outbox: Garantia de consistência em eventos
- Secret Manager/Vault: Gerenciamento seguro de credenciais
- Padronização de Logs: Uniformização de formato de logs
- OpenTelemetry: Observabilidade padronizada
- Service Template: Templates para novos serviços
Eventos representam situações que ocorreram no passado e normalmente produzem efeitos colaterais no sistema. Por exemplo, quando a porta de um carro abre, a luz interna é acionada automaticamente.
Eventos podem ser processados de forma interna (dentro da aplicação) ou externa (entre sistemas). Domain Events são mudanças no estado interno da aplicação relacionadas às regras de negócio, frequentemente associados a agregados do domínio.
-
Event Notification: Comunicação concisa contendo informações mínimas
{ "order": 1, "status": "approved" } -
Event-Carried State Transfer: Formato completo para transferir informações detalhadas
{ "order": 1, "status": "approved", "products": [{"id": 1, "name": "Product A"}], "tax": "1%", "client": "John Doe" } -
Event Sourcing: Armazenamento de eventos em ordem cronológica com possibilidade de replay
Método tradicional requer consultas síncronas:
- Cliente compra produto → Verificar estoque → Atualizar catálogo → Emitir nota → Separar produtos...
Event Collaboration opera com informações já disponíveis através de eventos:
- Cliente comprou produto
- Estoque foi atualizado
- Catálogo foi modificado
- Nota fiscal foi emitida
- Erro foi tratado
- Descrição do produto foi alterada
Command Query Responsibility Segregation (CQRS) separa operações de leitura e escrita:
- Comando: Representa intenção de mudança sem retorno (ex: Criar Produto)
- Query: Foca na recuperação de dados
É possível utilizar bancos de dados separados:
- Escrita:
{ "id": 1, "product": 2, "category": 3 } - Leitura:
{ "id": 1, "product": "Carrinho", "categoria": "Brinquedo" }
CQRS combinado com Event Sourcing permite consolidação de dados através do replay de eventos, embora não seja obrigatório.
- Evento: Estrutura que carrega dados da ocorrência
- Operações: Ações executadas quando um evento é processado
- Gerenciador de eventos: Responsável por:
- Registrar eventos e suas operações correspondentes
- Despachar eventos para execução das operações