Event-driven architecture

1. Fundamentos da Arquitetura Orientada a Eventos

A Arquitetura Orientada a Eventos (EDA) é um estilo arquitetural onde a comunicação entre componentes ocorre através da produção, detecção e consumo de eventos. Um evento representa uma mudança de estado significativa no sistema — algo que aconteceu no passado e não pode ser desfeito. Diferentemente de chamadas síncronas como REST ou RPC, onde o cliente bloqueia aguardando resposta, na EDA os componentes são fracamente acoplados e se comunicam de forma assíncrona.

Os componentes-chave da EDA incluem:
- Produtores: geram eventos quando algo relevante ocorre
- Consumidores: reagem a eventos de seu interesse
- Barramento de eventos: canal lógico que transporta eventos
- Brokers: infraestrutura que gerencia o roteamento e persistência dos eventos

Exemplo de evento em formato JSON:

{
  "eventId": "a1b2c3d4",
  "eventType": "OrderPlaced",
  "timestamp": "2025-03-28T14:30:00Z",
  "data": {
    "orderId": "ORD-9876",
    "customerId": "CUST-123",
    "totalAmount": 250.00
  }
}

2. Padrões de Comunicação e Topologias

Existem três padrões principais de comunicação baseada em eventos:

Event Notification: o produtor notifica consumidores sobre mudanças, sem incluir dados completos. Consumidores buscam dados adicionais se necessário.

Event Streaming: todos os eventos são persistidos em ordem cronológica, permitindo reprocessamento e auditoria completa.

Event Sourcing: o estado atual do sistema é derivado exclusivamente da sequência de eventos armazenados.

Quanto às topologias, temos:
- Mediator Topology: um orquestrador central coordena o fluxo de eventos entre produtores e consumidores
- Broker Topology: não há mediador central; cada consumidor decide como reagir aos eventos

Garantias de entrega variam:

At-most-once:  evento pode ser perdido, nunca duplicado
At-least-once: evento sempre entregue, pode haver duplicatas
Exactly-once:  entrega garantida sem perda nem duplicação

3. Escalabilidade e Resiliência com Event Sourcing

No Event Sourcing, o event store é a fonte única da verdade. Cada evento é imutável e representa uma transação. Para reconstruir o estado atual de uma entidade, basta reproduzir todos os eventos relacionados na ordem correta.

Exemplo de reconstrução de estado:

Eventos do agregado "Pedido-9876":
1. OrderPlanned { items: ["A", "B"], total: 200 }
2. PaymentReceived { amount: 200, method: "credit_card" }
3. OrderShipped { trackingCode: "BR123456789" }

Estado reconstruído:
{
  orderId: "ORD-9876",
  items: ["A", "B"],
  status: "shipped",
  totalPaid: 200
}

Para consultas otimizadas, utilizam-se projeções e read models — visões materializadas dos eventos que podem ser consultadas rapidamente. Em caso de falhas, o replay de eventos permite recuperar o estado exato do sistema, desde que os consumidores sejam idempotentes.

4. Gerenciamento de Consistência e Complexidade

Sistemas distribuídos baseados em eventos operam tipicamente com consistência eventual — após um período, todos os nós convergem para o mesmo estado. Isso contrasta com consistência forte, onde toda leitura retorna o dado mais recente.

Para transações distribuídas, o padrão Saga coordena múltiplos serviços através de eventos compensatórios:

Saga de Pedido:
1. Serviço de Pedidos: cria pedido (evento: OrderCreated)
2. Serviço de Pagamento: processa pagamento (evento: PaymentProcessed)
3. Serviço de Estoque: reserva itens (evento: InventoryReserved)
4. Se falha no estoque → evento: PaymentRefunded (ação compensatória)
5. Se falha no pagamento → evento: OrderCancelled (ação compensatória)

Versionamento de eventos é crítico para evolução de esquemas. Estratégias comuns incluem:
- Adicionar novos campos opcionais sem quebrar consumidores antigos
- Criar novas versões de tipos de evento (ex: OrderPlacedV2)
- Utilizar schema registries para validar compatibilidade

5. Infraestrutura e Ferramentas para EDA

A escolha do broker impacta diretamente o design da arquitetura:

Ferramenta Caso de uso ideal Trade-offs
Apache Kafka Event streaming, replay, alta throughput Complexidade operacional, latência maior
RabbitMQ Roteamento flexível, mensageria tradicional Menor throughput em streaming
AWS SQS/SNS Serverless, integração com AWS Vendor lock-in, limitações de tamanho

Dead letter queues (DLQs) armazenam eventos que falharam repetidamente, permitindo análise posterior:

Configuração típica:
- maxRetries: 3
- retryDelay: 5 segundos (exponencial: 5s, 10s, 20s)
- deadLetterQueue: "orders-dlq"

Para observabilidade, ferramentas como OpenTelemetry permitem rastrear fluxos completos de eventos através de múltiplos serviços.

6. Padrões Avançados e Integração com Outras Arquiteturas

CQRS (Command Query Responsibility Segregation) complementa EDA separando comandos (escrita) de consultas (leitura). Eventos gerados por comandos alimentam read models otimizados para consultas.

Em migrações de sistemas monolíticos, o padrão Strangler Fig permite gradualmente extrair funcionalidades para microserviços orientados a eventos:

Fase 1: Monólito + evento de "pedido criado" publicado
Fase 2: Novo serviço de notificação consome o evento
Fase 3: Novo serviço de faturamento consome o mesmo evento
Fase 4: Monólito é desativado gradualmente

Padrões de resiliência incluem:
- Bulkhead: isolar consumidores em pools de recursos separados
- Timeout: limitar tempo de processamento de cada evento
- Circuit Breaker: interromper consumo quando serviço downstream falha

7. Casos de Uso e Considerações Finais

EDA brilha em cenários como:
- IoT: dispositivos geram milhões de eventos de sensores
- Pipelines de dados: processamento em tempo real de streams
- Sistemas de notificação: alertas baseados em eventos de negócio
- E-commerce: processamento assíncrono de pedidos e pagamentos

Armadilhas comuns incluem:
- Complexidade de depuração: rastrear fluxos de eventos entre múltiplos serviços
- Latência: consistência eventual pode não atender requisitos de tempo real
- Custo operacional: infraestrutura de brokers e armazenamento de eventos

Evite EDA quando:
- Requisitos de consistência imediata são inegociáveis
- O sistema é simples e não se beneficia do desacoplamento
- A equipe não tem maturidade para operar brokers e lidar com eventual consistency

A Arquitetura Orientada a Eventos oferece escalabilidade, resiliência e desacoplamento incomparáveis para sistemas distribuídos modernos, mas exige planejamento cuidadoso e investimento em ferramentas de observabilidade e governança de eventos.

Referências