Simulador de Eventos
Projete e trace fluxos de eventos entre microsserviços — desde a publicação até o consumo e as reações em cadeia.
Objetivo
Neste laboratório você vai projetar fluxos de eventos entre microsserviços, traçar seu percurso completo e antecipar os problemas que podem surgir em uma arquitetura event-driven.
Os eventos são o sistema nervoso de uma arquitetura distribuída. Entender como eles fluem é fundamental para projetar sistemas desacoplados e resilientes.
Conceitos prévios
Antes de começar, certifique-se de entender a diferença entre:
| Conceito | Descrição | Exemplo |
|---|---|---|
| Comando | Solicitação para fazer algo | CreateOrder |
| Evento | Notificação de algo que já aconteceu | OrderCreated |
| Query | Solicitação de informação | GetOrderStatus |
Os eventos são fatos imutáveis — algo que já ocorreu e não pode ser desfeito. Os comandos são intenções — podem ser rejeitados.
Exercício 1: Projetar um fluxo de eventos
Cenário
Um usuário compra um produto no seu e-commerce. Projete o fluxo completo de eventos desde o momento em que ele clica em “Comprar” até receber a confirmação.
Serviços envolvidos
- Serviço de Pedidos: cria e gerencia pedidos
- Serviço de Estoque: reserva e dá baixa no estoque
- Serviço de Pagamentos: processa a cobrança
- Serviço de Notificações: envia e-mails e push
- Serviço de Analytics: registra métricas de negócio
Sua tarefa
Complete o diagrama de eventos:
Usuário clica em "Comprar"
│
▼
[Serviço de Pedidos]
│ publica: OrderCreated { orderId, userId, items, total }
│
├──► [Serviço de Estoque]
│ consome: OrderCreated
│ ação: reservar estoque
│ publica: _______________
│
├──► [Serviço de Pagamentos]
│ consome: _______________
│ ação: processar cobrança
│ publica: _______________
│
├──► [Serviço de Notificações]
│ consome: _______________
│ ação: _______________
│
└──► [Serviço de Analytics]
consome: _______________
ação: _______________
Solução
Ver fluxo completo
Usuário clica em "Comprar"
│
▼
[Serviço de Pedidos]
│ publica: OrderCreated { orderId, userId, items, total }
│
├──► [Serviço de Estoque]
│ consome: OrderCreated
│ ação: reservar estoque para os itens
│ publica: StockReserved { orderId, items }
│ ou StockInsufficient { orderId, items }
│
├──► [Serviço de Pagamentos]
│ consome: StockReserved
│ ação: processar cobrança com o provedor
│ publica: PaymentCompleted { orderId, transactionId }
│ ou PaymentFailed { orderId, reason }
│
├──► [Serviço de Notificações]
│ consome: PaymentCompleted
│ ação: enviar e-mail de confirmação ao usuário
│ consome: PaymentFailed
│ ação: enviar e-mail de falha ao usuário
│
└──► [Serviço de Analytics]
consome: OrderCreated, StockReserved, PaymentCompleted
ação: registrar métricas de conversão e receita
Exercício 2: Lidar com o caminho infeliz
Cenário
O que acontece quando algo falha no meio do fluxo? Projete as compensações.
Caso 1: O estoque foi reservado, mas o pagamento falhou
OrderCreated → StockReserved → PaymentFailed
│
▼
E agora?
Sua tarefa: Qual evento o serviço de pagamentos deve publicar? Quem o consome? Que ação ele toma?
Ver solução
PaymentFailed { orderId, reason }
│
├──► [Serviço de Estoque]
│ consome: PaymentFailed
│ ação: liberar estoque reservado
│ publica: StockReleased { orderId, items }
│
├──► [Serviço de Pedidos]
│ consome: PaymentFailed
│ ação: marcar pedido como falho
│ publica: OrderCancelled { orderId, reason }
│
└──► [Serviço de Notificações]
consome: OrderCancelled
ação: notificar o usuário de que o pagamento falhou
Este é o padrão Saga com coreografia: cada serviço reage aos eventos e executa compensações quando algo falha. Não há um orquestrador central.
Caso 2: O serviço de estoque está fora do ar
OrderCreated → [Estoque: FORA DO AR] → ???
Sua tarefa: O que acontece com o evento OrderCreated? Ele se perde? É reprocessado?
Ver solução
Se você usar um message broker com filas duráveis (RabbitMQ, Kafka):
- O evento
OrderCreatedfica na fila aguardando - Quando o serviço de estoque volta, consome os eventos pendentes
- O processamento continua normalmente (com atraso)
Chave: A fila atua como buffer temporário. O evento não se perde enquanto a fila for durável e as mensagens forem persistentes.
Consideração: Se o serviço ficar fora do ar por muito tempo, a fila cresce. Você precisa de:
- Alertas por tamanho de fila
- TTL nas mensagens para evitar processar eventos muito antigos
- Lógica de compensação caso o evento já não seja relevante
Exercício 3: Ordenação de eventos
O problema
Dois eventos chegam ao serviço de estoque:
StockUpdated { productId: "ABC", quantity: 100 }(timestamp: 10:00:01)StockUpdated { productId: "ABC", quantity: 50 }(timestamp: 10:00:00)
O evento 2 foi publicado primeiro, mas chegou depois. Se você processar na ordem de chegada, o estoque fica em 50 (incorreto — deveria ser 100).
Sua tarefa
Como garantir a ordem correta? Avalie estas estratégias:
| Estratégia | Prós | Contras |
|---|---|---|
| Ordenar por timestamp | Simples | Relógios não sincronizados entre serviços |
| Número de sequência | Ordem garantida | Requer coordenação entre publishers |
| Partição por key | Ordem dentro da partição | Limita o paralelismo |
| Versão otimista | Não requer ordem global | Requer lógica de resolução de conflitos |
Ver recomendação
A estratégia mais prática para a maioria dos casos é partição por key:
- No Kafka: usar
productIdcomo partition key - Todos os eventos do mesmo produto vão para a mesma partição
- Dentro de uma partição, a ordem está garantida
- Produtos diferentes são processados em paralelo
Para casos em que você precisa de ordem global, use um número de sequência gerado pelo publisher e rejeite eventos com sequência menor que a última processada.
Exercício 4: Projete seu próprio fluxo
Sua tarefa
Escolha um destes cenários e projete o fluxo completo de eventos:
Opção A: Sistema de reservas de hotel
- Serviços: Reservas, Quartos, Pagamentos, Notificações
- Fluxo: usuário reserva → verificar disponibilidade → cobrar → confirmar
Opção B: Plataforma de delivery
- Serviços: Pedidos, Restaurantes, Entregadores, Tracking, Notificações
- Fluxo: usuário pede → restaurante aceita → entregador designado → entrega
Opção C: Sistema de assinaturas
- Serviços: Usuários, Assinaturas, Pagamentos, Acesso, Notificações
- Fluxo: usuário assina → cobrança recorrente → renovação/cancelamento
Para cada um, defina:
- Os eventos principais (caminho feliz)
- Os eventos de compensação (caminho infeliz)
- Qual serviço publica e quem consome cada evento
- Como você lida com as falhas em cada etapa
Reflexão
- Quantos eventos você precisou para um fluxo “simples”?
- Quão difícil foi projetar as compensações?
- Você preferiria um orquestrador central (Saga orquestrada) ou coreografia?
- Como você depuraria um problema em um fluxo de 5+ eventos?
Os sistemas event-driven são poderosos, mas complexos. A chave é projetar os fluxos antes de escrever código — e sempre pensar no que acontece quando algo falha.