Arquitetura Event-Driven

Introdução à Arquitetura Event-Driven com KEDA e RabbitMQ

A necessidade de construir sistemas escaláveis e reativos tem levado cada vez mais times a adotar o modelo Event-Driven Architecture (EDA).
Em vez de depender de integrações diretas entre serviços, a comunicação é feita por eventos assíncronos, o que reduz acoplamento e melhora a performance geral.

Neste guia prático — um verdadeiro KEDA RabbitMQ tutorial — você aprenderá a:

  • Implementar um microserviço de auditoria orientado a eventos
  • Integrar RabbitMQ como broker de mensagens
  • Configurar o KEDA para escalar automaticamente o consumo no Kubernetes

Índice

  1. O que é uma Arquitetura Orientada a Eventos (Event-Driven Architecture)
  2. Tecnologias e Ferramentas Usadas
  3. Cenário Proposto: Microserviço de Auditoria Event-Driven
  4. Estrutura do Projeto Event-Driven com RabbitMQ e KEDA
  5. Implementação Passo a Passo
  6. Testando o Autoscaling no Kubernetes
  7. Melhores Práticas e Observabilidade
  8. Conclusão — Vantagens da Arquitetura Event-Driven com KEDA e RabbitMQ
  9. Referências e Leitura Complementar

1. O que é uma Arquitetura Orientada a Eventos (Event-Driven Architecture)

Uma arquitetura orientada a eventos é baseada na ideia de que cada ação relevante dentro do sistema (como a criação de um pedido ou a atualização de um registro) gera um evento.
Esses eventos são publicados em uma fila e processados de maneira independente pelos serviços interessados.

1.1. Benefícios da Arquitetura Event-Driven

  • Desacoplamento entre serviços — cada componente conhece apenas os eventos, não as implementações.
  • Escalabilidade automática — é possível escalar consumidores conforme a fila cresce.
  • Resiliência — falhas temporárias não afetam o sistema, pois as mensagens permanecem na fila.
  • Flexibilidade — novos consumidores podem ser adicionados sem impacto no restante da arquitetura.

1.2. Fluxo de Comunicação

O diagrama abaixo ilustra como funciona o fluxo de comunicação em uma arquitetura orientada a eventos:

Fluxo de Comunicação Event-Driven

Como podemos observar:

  • Produtores enviam eventos para o Message Broker de forma assíncrona
  • O Message Broker (RabbitMQ) gerencia as filas e distribui as mensagens
  • Consumidores independentes processam os eventos de suas respectivas filas
  • Cada serviço pode escalar independentemente conforme a demanda

2. Tecnologias e Ferramentas Usadas

Tecnologia Função
RabbitMQ Gerencia o roteamento e o armazenamento das mensagens
KEDA Faz o autoscaling com base no tamanho da fila RabbitMQ
Spring Boot Implementação do microserviço de auditoria
Docker & Kubernetes Containerização e orquestração da aplicação
Prometheus & Grafana Monitoramento e observabilidade

Essas ferramentas, em conjunto, formam a base para uma arquitetura cloud-native moderna e elástica.

3. Cenário Proposto: Microserviço de Auditoria Event-Driven

O Audit Service será responsável por registrar todas as ações críticas do sistema. Cada vez que um evento ocorre — por exemplo, uma criação ou exclusão de registro —, uma mensagem é enviada para o RabbitMQ, e o serviço de auditoria processa esse evento de forma assíncrona.

3.1. Fluxo Geral da Solução

Fluxo Geral da Solução

4. Estrutura do Projeto Event-Driven com RabbitMQ e KEDA

event-driven-audit/
├── audit-service/
│   ├── src/
│   │   ├── main/java/com/example/audit/
│   │   │   ├── controller/
│   │   │   ├── service/
│   │   │   ├── consumer/
│   │   │   └── model/
│   ├── resources/
│   │   └── application.yml
├── docker-compose.yml
└── k8s/
    ├── deployment.yml
    ├── keda-scaledobject.yml
    └── rabbitmq-config.yml

Uma organização mínima como a mostrada acima separa com clareza três frentes distintas do projeto: o código do serviço, o ambiente local de desenvolvimento e os manifestos de execução no Kubernetes. Essa divisão reduz atritos no dia a dia e evita que detalhes operacionais vazem para o domínio de negócio.

  • audit-service: módulo do microserviço em si. Aqui vive tudo que transforma eventos em registros de auditoria persistidos.
  • src/main/java/com/example/audit/controller: camada de entrada HTTP do serviço (consulta de auditorias, endpoints de saúde/depuração). Mesmo em soluções dirigidas a eventos, é comum expor leituras e verificações via API.
  • src/main/java/com/example/audit/service: regras de negócio e orquestração de persistência. A ideia é manter a lógica de auditoria concentrada aqui, isolando detalhes de mensageria e transporte.
  • src/main/java/com/example/audit/consumer: integração com o RabbitMQ. Consumidores anotados (por exemplo, com @RabbitListener) transformam mensagens da fila em chamadas para a camada de serviço, tratando idempotência, conversão e validação.
  • src/main/java/com/example/audit/model: modelos de domínio e DTOs dos eventos. O contrato do evento de auditoria mora aqui (campos, tipos e semântica), facilitando a evolução sem quebrar consumidores.
  • resources/application.yml: configurações do serviço. Centraliza conexões (RabbitMQ, banco), nomes de filas e parâmetros sensíveis à execução. Prefira variáveis de ambiente e perfis do Spring para distinguir locais, homologação e produção.
  • docker-compose.yml: apoio ao desenvolvimento. Sobe o RabbitMQ (e, se necessário, banco) para testes locais rápidos, espelhando os nomes de filas e credenciais usados pelos manifestos do cluster.
  • k8s/deployment.yml: definição do pod do audit-service no Kubernetes (imagem, portas, variáveis, requests/limits). Esse arquivo não conhece fila nem gatilhos — apenas o runtime do serviço.
  • k8s/keda-scaledobject.yml: vínculo entre a carga da fila e o autoscaling. Aqui declaramos qual fila observar, limites de réplicas e a política de reação do KEDA.
  • k8s/rabbitmq-config.yml: recursos de infraestrutura relacionados ao broker (credenciais, vhost, políticas ou bindings, conforme a abordagem da equipe). Mantê-los versionados evita configurações manuais e divergências entre ambientes.

Com essa estrutura, cada mudança encontra seu lugar natural: contratos e lógica no audit-service, experiência local no docker-compose.yml e comportamento de execução/escala nos arquivos de k8s/. O resultado é um ciclo de desenvolvimento previsível e um caminho de deploy sem surpresas.

5. Implementação Passo a Passo

Implementação Passo a Passo

1️⃣ Subindo o RabbitMQ Localmente

No arquivo docker-compose.yml:

version: "3.8"
services:
  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
      - "15672:15672"
    environment:
      RABBITMQ_DEFAULT_USER: user
      RABBITMQ_DEFAULT_PASS: pass

Acesse o Painel do RabbitMQ.

2️⃣ Criando o Microserviço de Auditoria (Audit Microservice)

application.yml

spring:
  rabbitmq:
    host: rabbitmq
    username: user
    password: pass
  datasource:
    url: jdbc:postgresql://db/audit
    username: postgres
    password: postgres

Entidade AuditEvent.java

@Entity
public class AuditEvent {
    @Id
    @GeneratedValue
    private Long id;
    private String action;
    private String entity;
    private String user;
    private LocalDateTime timestamp;
}

Consumidor AuditConsumer.java

@Component
public class AuditConsumer {

    private final AuditService auditService;

    public AuditConsumer(AuditService auditService) {
        this.auditService = auditService;
    }

    @RabbitListener(queues = "audit.queue")
    public void consume(AuditEvent event) {
        auditService.save(event);
    }
}

Esse componente consome mensagens da fila e grava os eventos de auditoria no banco.

3️⃣ Deploy do Serviço no Kubernetes

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: audit-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: audit-service
  template:
    metadata:
      labels:
        app: audit-service
    spec:
      containers:
        - name: audit-service
          image: yourrepo/audit-service:latest
          ports:
            - containerPort: 8080

4️⃣ Configurando o KEDA para Autoscaling com RabbitMQ

keda-scaledobject.yml

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: audit-service-scaler
spec:
  scaleTargetRef:
    name: audit-service
  minReplicaCount: 1
  maxReplicaCount: 10
  triggers:
  - type: rabbitmq
    metadata:
      queueName: audit.queue
      host: RabbitMQConnectionString
      queueLength: "10"

Quando a fila audit.queue acumular mensagens, o KEDA aumentará o número de pods. Quando o volume cair, ele reduzirá automaticamente — otimizando custo e recursos.

6. Testando o Autoscaling no Kubernetes

  1. Gere eventos de exemplo para popular a fila.
  2. Observe o RabbitMQ crescendo em mensagens pendentes.
  3. Verifique o KEDA ajustando dinamicamente as réplicas do audit-service.
  4. Veja os logs confirmando o processamento em paralelo.
Autoscaling com KEDA

7. Melhores Práticas e Observabilidade

  • Use logs estruturados (JSON) para facilitar a correlação e o parsing em ferramentas de monitoramento.
  • Implemente correlation IDs para rastrear eventos ponta a ponta.
  • Exponha métricas para Prometheus e crie dashboards no Grafana.
  • Configure Dead Letter Queues (DLQs) para mensagens problemáticas.

Essas práticas aumentam a confiabilidade e tornam o sistema observável e sustentável.

8. Conclusão — Vantagens da Arquitetura Event-Driven com KEDA e RabbitMQ

Adotar uma arquitetura event-driven com RabbitMQ e KEDA permite que seu sistema:

  • Processe eventos de forma assíncrona
  • Escale automaticamente conforme a carga
  • Seja resiliente, modular e fácil de evoluir

Nosso microserviço de auditoria demonstrou na prática como unir mensageria, autoscaling e boas práticas em uma aplicação moderna.

Próximos passos sugeridos:

  • Adicionar retries e mecanismos de fallback
  • Criar DLQs para mensagens não processadas
  • Evoluir o design para event streaming (Kafka, Pulsar)

9. Referências e Leitura Complementar