Como sincronizar dados entre sistemas legados e modernos com event bridges
1. O desafio da sincronização entre mundos tecnológicos distintos
1.1. Sistemas legados: características, limitações e a importância de mantê-los operacionais
Sistemas legados são a espinha dorsal de muitas organizações. Construídos ao longo de décadas, eles armazenam dados críticos de clientes, transações financeiras e inventários. Suas características típicas incluem bancos de dados relacionais monolíticos, interfaces baseadas em arquivos (CSV, XML) e APIs REST antigas com documentação escassa. Apesar de sua estabilidade, esses sistemas apresentam limitações severas: baixa escalabilidade horizontal, dificuldade de integração com tecnologias modernas e processos de deploy manuais. No entanto, substituí-los completamente é inviável financeira e operacionalmente.
1.2. Sistemas modernos: microsserviços, APIs assíncronas e a necessidade de dados em tempo real
Do outro lado, temos os sistemas modernos — construídos com microsserviços, containers e filas de mensagens. Eles exigem dados em tempo real para alimentar dashboards, motores de recomendação e aplicações mobile. APIs síncronas não são suficientes; o modelo assíncrono, baseado em eventos, tornou-se padrão para garantir desacoplamento e resiliência.
1.3. Problemas comuns: inconsistência de dados, latência, acoplamento e retrabalho manual
A integração direta entre esses mundos gera problemas clássicos:
- Inconsistência de dados: o sistema legado atualiza um registro, mas o moderno fica desatualizado por minutos ou horas.
- Latência: consultas frequentes ao banco legado geram lentidão generalizada.
- Acoplamento forte: alterações na API do legado quebram o sistema moderno.
- Retrabalho manual: equipes criam scripts de sincronização periódica que falham silenciosamente.
2. Fundamentos de Event Bridges e o padrão de integração assíncrona
2.1. O que é um Event Bridge: conceito, componentes e casos de uso
Um Event Bridge é um intermediário que conecta produtores de eventos (fontes de dados) a consumidores (sistemas que precisam desses dados). Seus componentes principais são:
- Produtores: sistemas que emitem eventos (ex: "cliente_atualizado", "pedido_criado").
- Barramento: canal central que roteia eventos para os consumidores corretos.
- Consumidores: serviços que processam eventos e atualizam seus estados.
Casos de uso típicos incluem sincronização de catálogos de produtos, replicação de dados de clientes entre CRM e ERP, e atualização de dashboards em tempo real.
2.2. Diferenças entre Event Bridge, filas de mensagens e ETL tradicional
| Característica | Event Bridge | Filas (RabbitMQ, SQS) | ETL Tradicional |
|---|---|---|---|
| Processamento | Tempo real | Tempo real | Batch (horário) |
| Roteamento | Baseado em conteúdo | Fila única | Pré-definido |
| Persistência | Curta/média duração | Curta duração | Longa duração |
| Acoplamento | Baixo | Médio | Alto |
2.3. Vantagens do modelo orientado a eventos para sincronização
O modelo orientado a eventos oferece:
- Desacoplamento: produtores e consumidores não precisam se conhecer.
- Escalabilidade: consumidores podem ser escalados independentemente.
- Resiliência: falhas em um consumidor não afetam os demais.
3. Mapeamento e modelagem de eventos entre sistemas legados e modernos
3.1. Identificando fontes de dados no sistema legado
As fontes típicas incluem:
- Tabelas de bancos relacionais (Oracle, SQL Server, DB2)
- Arquivos de log ou flat files gerados por processos batch
- APIs REST antigas com endpoints limitados
3.2. Desenho de eventos canônicos: schema unificado, versionamento e campos obrigatórios
Crie um schema canônico que represente o dado de forma neutra:
{
"eventId": "uuid",
"eventVersion": "1.0",
"eventType": "ClienteAtualizado",
"timestamp": "2025-03-21T14:30:00Z",
"data": {
"id": "12345",
"nome": "Maria Silva",
"email": "maria@exemplo.com",
"telefone": "+5511999999999"
}
}
Campos obrigatórios: eventId (único), eventVersion, eventType, timestamp, data. Versionamento permite evolução sem quebrar consumidores antigos.
3.3. Estratégias de transformação: adaptadores, normalização e enriquecimento
Adaptadores convertem dados do formato legado para o canônico:
// Adaptador para sistema legado em COBOL
function transformarClienteLegado(registroLegado) {
return {
id: registroLegado.cod_cliente,
nome: registroLegado.nm_cliente.trim(),
email: registroLegado.email_cliente?.toLowerCase(),
telefone: formatarTelefone(registroLegado.tel_contato)
};
}
Normalização: remover duplicatas, padronizar formatos. Enriquecimento: adicionar dados de contexto (geolocalização, segmentação).
4. Arquitetura prática de um Event Bridge híbrido
4.1. Componentes essenciais: change data capture (CDC) no legado, barramento de eventos e filas de retry
A arquitetura típica inclui:
- CDC (Change Data Capture): ferramenta como Debezium que monitora o log de transações do banco legado e emite eventos a cada INSERT, UPDATE ou DELETE.
- Barramento de eventos: AWS EventBridge, Apache Kafka ou RabbitMQ roteiam eventos.
- Filas de retry: eventos que falham vão para uma fila separada para reprocessamento.
4.2. Roteamento inteligente: filtros, tópicos e roteamento baseado em conteúdo
Configure regras de roteamento:
Regra 1: Se eventType = "ClienteAtualizado" E data.pais = "BR"
-> Enviar para tópico "clientes-brasil"
Regra 2: Se eventType = "PedidoCriado" E data.valor > 10000
-> Enviar para tópico "pedidos-vip"
4.3. Garantia de entrega: idempotência, exactly-once processing e dead letter queues
- Idempotência: cada evento deve ter um
eventIdúnico; consumidores verificam se já processaram aquele ID. - Exactly-once: combinação de idempotência + confirmação de consumo (commit offset).
- Dead Letter Queue (DLQ): eventos que falham após N tentativas vão para uma fila de análise manual.
5. Implementação passo a passo com exemplos concretos
5.1. Captura de mudanças no sistema legado: polling vs. triggers vs. CDC (exemplo com Debezium)
Polling: consulta periódica ao banco (ineficiente para dados em tempo real).
Triggers: gatilhos no banco que chamam uma API (impactam performance).
CDC: ideal. Exemplo com Debezium conectado a um banco PostgreSQL legado:
// Configuração Debezium (JSON)
{
"name": "conector-legado-clientes",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "192.168.1.100",
"database.port": "5432",
"database.user": "debezium",
"database.password": "senha",
"database.dbname": "erp_legado",
"table.include.list": "public.clientes",
"topic.prefix": "legado"
}
}
A cada mudança na tabela clientes, Debezium publica um evento no tópico legado.public.clientes.
5.2. Configuração do barramento de eventos: AWS EventBridge, Kafka ou RabbitMQ (exemplo de roteamento)
Exemplo com AWS EventBridge:
// Regra de roteamento (JSON)
{
"EventPattern": {
"source": ["legado.clientes"],
"detail-type": ["ClienteAtualizado"]
},
"Targets": [
{
"Arn": "arn:aws:sqs:us-east-1:123456789012:fila-modernizacao",
"InputTransformer": {
"InputPathsMap": {
"id": "$.detail.after.id",
"nome": "$.detail.after.nome"
},
"InputTemplate": "{\"eventId\": \"<id>\", \"nome\": \"<nome>\"}"
}
}
]
}
5.3. Consumo no sistema moderno: handlers assíncronos, validação e atualização do estado final
Handler em Node.js consumindo da fila SQS:
async function handler(event) {
const body = JSON.parse(event.Records[0].body);
// Validação
if (!body.eventId || !body.nome) {
throw new Error('Evento inválido');
}
// Idempotência
const jaProcessado = await redis.get(body.eventId);
if (jaProcessado) return;
// Atualização no banco moderno
await db.clientes.upsert({
where: { id: body.id },
update: { nome: body.nome },
create: { id: body.id, nome: body.nome }
});
// Marca como processado
await redis.set(body.eventId, 'processed', 'EX', 86400);
}
6. Tratamento de falhas, consistência e monitoramento
6.1. Estratégias para lidar com falhas de rede, downtime do legado e eventos duplicados
- Falhas de rede: retry exponencial (3, 9, 27 segundos) com máximo de 5 tentativas.
- Downtime do legado: fila de retry separada; eventos são reprocessados quando o legado volta.
- Eventos duplicados: idempotência via
eventIdúnico.
6.2. Consistência eventual vs. consistência forte: trade-offs e compensações
- Consistência eventual: aceita que o sistema moderno fique momentaneamente desatualizado (segundos). Ideal para catálogos de produtos.
- Consistência forte: todas as réplicas são atualizadas antes de confirmar. Mais lenta, mas necessária para dados financeiros.
6.3. Observabilidade: logs estruturados, métricas de latência, dashboards e alertas
Métricas essenciais:
# Métricas Prometheus
event_bridge_eventos_recebidos_total{source="legado"} 1500
event_bridge_eventos_processados_total{consumer="moderno"} 1495
event_bridge_latencia_segundos{percentil="99"} 2.3
event_bridge_dlq_contagem{queue="clientes"} 5
Dashboards no Grafana mostram throughput, latência e taxa de erro. Alertas no PagerDuty para DLQ > 0.
7. Boas práticas e armadilhas comuns em projetos reais
7.1. Versionamento de eventos: como evoluir schemas sem quebrar consumidores existentes
Use versionamento semântico no schema:
// Versão 1.0
{ "eventVersion": "1.0", "data": { "nome": "string" } }
// Versão 2.0 (adiciona campo email)
{ "eventVersion": "2.0", "data": { "nome": "string", "email": "string" } }
Consumidores antigos ignoram campos desconhecidos. Consumidores novos usam o campo email.
7.2. Evitando a "bola de neve": limites de throughput, backpressure e circuit breakers
- Limites de throughput: configure throttling no barramento (ex: 100 eventos/segundo por consumidor).
- Backpressure: se o consumidor está lento, o barramento acumula eventos na fila (visível no dashboard).
- Circuit breaker: se a taxa de erro ultrapassar 50% em 1 minuto, pausa o consumo e alerta.
7.3. Casos de sucesso e erros frequentes: migração gradual, testes de integração e rollback planejado
Caso de sucesso: empresa de logística migrou dados de 20 tabelas legadas para microsserviços em 3 meses, usando CDC + EventBridge. Zero downtime.
Erro frequente: esquecer de configurar idempotência. Resultado: registros duplicados no banco moderno.
Migração gradual: sincronize primeiro dados de clientes (baixo risco), depois pedidos (médio risco), por último transações financeiras (alto risco). Cada etapa com rollback planejado (voltar a sincronização manual).
Referências
- AWS EventBridge Documentation — Guia oficial da AWS sobre EventBridge, incluindo exemplos de roteamento e integração com sistemas legados.
- Debezium CDC Documentation — Documentação completa do Debezium para captura de mudanças em bancos relacionais (PostgreSQL, MySQL, Oracle).
- Event-Driven Architecture on AWS — Whitepaper da AWS sobre arquitetura orientada a eventos, incluindo padrões de integração híbrida.
- Kafka Connect for Legacy Systems — Artigo da Confluent sobre integração de sistemas legados com Kafka e Kafka Connect.
- Martin Fowler: Event Sourcing — Artigo clássico de Martin Fowler sobre event sourcing e padrões de sincronização assíncrona.
- Idempotency in Event-Driven Systems — Blog da AWS sobre implementação de idempotência em handlers de eventos usando Lambda e DynamoDB.
- Observability for Event Bridges — Tutorial da Grafana sobre monitoramento de arquiteturas orientadas a eventos com Prometheus e dashboards.