RabbitMQ vs Apache Kafka: mensageria vs streaming

1. Fundamentos: mensageria tradicional vs streaming de eventos

1.1. O que é mensageria: filas, exchanges, roteamento e entrega ponto a ponto

A mensageria tradicional é um padrão arquitetural onde produtores enviam mensagens para um intermediário (broker) que as encaminha para consumidores. O modelo clássico envolve filas FIFO, exchanges (roteadores) e bindings que definem regras de entrega. A mensagem é removida da fila após ser consumida com sucesso.

Exemplo de roteamento com RabbitMQ:
- Exchange do tipo "direct" com routing key "pedidos.criados"
- Fila "fila_pedidos" vinculada a essa exchange
- Produtor envia mensagem → Exchange → Roteia para fila → Consumidor processa
- Após ACK do consumidor, mensagem é removida permanentemente

1.2. O que é streaming: logs imutáveis, particionamento e replay de eventos

Streaming de eventos trata dados como um log imutável e ordenado. Cada evento é armazenado em um tópico particionado, e consumidores avançam por offsets. Diferente da mensageria, os eventos não são removidos após consumo — ficam disponíveis para replay por novos consumidores ou para processamento retrospectivo.

Modelo Kafka:
- Tópico "pagamentos" com 3 partições (p0, p1, p2)
- Produtor envia evento com chave "usuario_123" → Partição p1 (hash da chave)
- Consumidor lê offset 42 da partição p1
- Evento permanece no log mesmo após leitura (retenção configurável: 7 dias, 1GB)
- Novo consumidor pode ler desde o offset 0 (replay completo)

1.3. Casos de uso típicos: sistemas transacionais vs pipelines de dados em tempo real

Cenário Ferramenta recomendada Motivo
Processamento de pedidos com confirmação RabbitMQ Entrega garantida, ACKs, DLQ
Pipeline de eventos de clique em site Kafka Alto throughput, replay, análise histórica
Notificações em tempo real para usuários RabbitMQ Roteamento flexível por exchange
Agregação de logs de microsserviços Kafka Log imutável, múltiplos consumidores

2. Arquitetura e modelo de dados

2.1. RabbitMQ: broker centralizado, exchanges e filas

RabbitMQ opera com um broker central (ou cluster pequeno). As mensagens passam por exchanges que aplicam regras de roteamento para filas. Existem quatro tipos principais de exchange:

  • Direct: roteia por routing key exata
  • Topic: roteia por padrão curinga (ex: pedidos.*)
  • Fanout: entrega para todas as filas vinculadas
  • Headers: roteia por cabeçalhos HTTP-like
Configuração de exchange topic no RabbitMQ:
- Exchange: "eventos.sistema"
- Bindings: "fila_erros" com routing key "erro.#"
- Bindings: "fila_auditoria" com routing key "#.auditoria"
- Mensagem com routing key "erro.critico.auditoria" → entregue em ambas filas

2.2. Apache Kafka: clusters distribuídos, tópicos particionados e offsets

Kafka é distribuído por natureza. Tópicos são divididos em partições, cada uma com líder e seguidores (replicação). Produtores escrevem em partições específicas; consumidores leem offsets sequenciais.

Estrutura de um tópico Kafka:
- Tópico: "transacoes_bancarias"
- Partições: 6 (distribuídas em 3 brokers)
- Fator de replicação: 3 (cada partição em 3 brokers diferentes)
- Retenção: 168 horas (7 dias) ou 50GB, o que ocorrer primeiro
- Compactação: habilitada para manter apenas último valor por chave

2.3. Comparação de persistência

Característica RabbitMQ Kafka
Remoção após consumo Sim (padrão) Não
Retenção configurável Limitada (TTL por mensagem/fila) Sim (tempo ou tamanho)
Replay de mensagens Complexo (requer reenvio) Nativo (reset de offset)
Armazenamento em disco Fila + mensagens individuais Log segmentado sequencial

3. Garantias de entrega e confiabilidade

3.1. RabbitMQ: confirmações, filas duráveis e dead letter queues

RabbitMQ oferece confirmações manuais (ACK) onde o consumidor sinaliza processamento bem-sucedido. Filas e mensagens podem ser marcadas como duráveis (persistem em disco). Dead Letter Queues (DLQ) capturam mensagens rejeitadas ou com TTL expirado.

Configuração de confiabilidade no RabbitMQ:
- Fila declarada como: durable=true, auto-delete=false
- Consumidor com autoAck=false
- Se processamento falha: basicNack(requeue=false) → mensagem vai para DLQ
- DLQ configurada com TTL e roteamento para análise manual

3.2. Kafka: replicação por partição, ISR e acknowledgments

Kafka replica cada partição em múltiplos brokers. O conjunto ISR (In-Sync Replicas) garante que apenas réplicas atualizadas participam da eleição de líder. O parâmetro acks controla a confiabilidade:

  • acks=0: sem confirmação (mais rápido, risco de perda)
  • acks=1: líder confirma (padrão, perda se líder falha antes da réplica)
  • acks=all: todas as réplicas ISR confirmam (mais seguro, maior latência)
Configuração de produtor Kafka para máxima confiabilidade:
- acks=all
- min.insync.replicas=2 (broker exige no mínimo 2 réplicas sincronizadas)
- retries=5 com backoff exponencial
- enable.idempotence=true (evita duplicatas em retentativas)

3.3. Trade-offs entre perda de dados e latência

Cenário RabbitMQ Kafka
Latência mínima ~microssegundos (em memória) ~milissegundos (escrita em disco)
Perda zero Possível com ACKs + duráveis Possível com acks=all + replicação
Throughput máximo ~dezenas de milhares/s ~milhões de mensagens/s

4. Desempenho e escalabilidade

4.1. Throughput e latência

RabbitMQ é otimizado para latência baixa em cargas moderadas (até 50.000 msg/s). Kafka foi projetado para alto throughput (centenas de milhares a milhões de msg/s) utilizando escrita sequencial em disco e zero-copy.

Benchmark simplificado (mensagens de 1KB):
- RabbitMQ: 30.000 msg/s, latência média 2ms
- Kafka: 500.000 msg/s, latência média 10ms
- Diferença: Kafka ~16x mais throughput, 5x mais latência

4.2. Escalabilidade horizontal

RabbitMQ escala adicionando nós ao cluster, mas filas têm limitações (leader em um nó). Kafka escala naturalmente aumentando partições e brokers — cada partição pode ser líder em um broker diferente.

Cenário de escala:
- RabbitMQ: cluster de 3 nós, fila líder no nó A (gargalo se fila única)
- Kafka: 6 partições em 3 brokers (2 partições líder por broker, balanceamento automático)
- Kafka permite adicionar partições sem redimensionar cluster

4.3. Gerenciamento de backpressure

RabbitMQ usa prefetch count para controlar quantas mensagens são enviadas por vez ao consumidor. Kafka monitora consumer lag (diferença entre último offset produzido e último consumido).

Configuração de backpressure:
- RabbitMQ: channel.basicQos(10) → consumidor recebe no máximo 10 mensagens não confirmadas
- Kafka: consumer.poll(100ms) + max.poll.records=500 → consumidor busca lotes
- Métrica chave Kafka: consumer_lag (quanto maior, mais backlog)

5. Roteamento e flexibilidade de consumo

5.1. RabbitMQ: roteamento complexo com bindings

RabbitMQ permite padrões de roteamento extremamente flexíveis. Uma mensagem pode ser entregue a múltiplas filas ou nenhuma (se não houver binding correspondente). Exchanges headers permitem roteamento baseado em metadados arbitrários.

Roteamento avançado RabbitMQ:
- Exchange headers: encaminha para fila se cabeçalho "prioridade" = "alta"
- Exchange topic: "estoque.#" captura "estoque.entrada", "estoque.saida", etc.
- Exchange fanout: entrega cópia para todas as filas (publish/subscribe puro)

5.2. Kafka: consumidores em grupo e rebalanceamento

Kafka organiza consumidores em grupos. Cada partição é consumida por exatamente um consumidor no grupo. Se um consumidor falha, o rebalanceamento redistribui as partições automaticamente.

Grupo de consumidores Kafka:
- Grupo "processadores_pagamento"
- 3 consumidores, 6 partições (2 partições por consumidor)
- Consumidor 1 falha → rebalanceamento → consumidores 2 e 3 assumem 3 partições cada
- Offsets são commitados automaticamente ou manualmente

5.3. Suporte a filas temporárias, RPC e publish/subscribe

Funcionalidade RabbitMQ Kafka
Filas temporárias Sim (auto-delete, exclusive) Não (tópicos são permanentes)
RPC síncrono Sim (fila de resposta + correlation ID) Não (ideal para assíncrono)
Publish/subscribe Exchange fanout Múltiplos grupos de consumidores

6. Ecossistema e integrações

6.1. RabbitMQ: protocolos e plugins

RabbitMQ suporta múltiplos protocolos: AMQP 0-9-1 (nativo), MQTT (IoT), STOMP (simples). Possui plugins para gerenciamento via UI, Prometheus, e integração com sistemas legados.

Plugins comuns RabbitMQ:
- rabbitmq_management: interface web (porta 15672)
- rabbitmq_prometheus: métricas para Prometheus
- rabbitmq_mqtt: suporte a protocolo MQTT
- rabbitmq_shovel: movimentação de mensagens entre brokers

6.2. Kafka: Kafka Connect, Streams e KSQL

Kafka possui ecossistema robusto: Kafka Connect para integração com bancos (JDBC, MongoDB, Elasticsearch), Kafka Streams para processamento stateful, e KSQL para consultas SQL-like em streams.

Pipeline típico Kafka:
- Kafka Connect Source (PostgreSQL) → Tópico "pedidos" → KSQL (agregação) → Tópico "relatorios" → Kafka Connect Sink (Elasticsearch)
- Processamento em tempo real: Kafka Streams para windowed aggregations
- Monitoramento: Confluent Control Center ou Prometheus + Grafana

6.3. Operação e monitoramento

Ferramenta RabbitMQ Kafka
UI nativa rabbitmq_management Confluent Control Center (pago)
Métricas Prometheus exporter JMX + Prometheus
Logs RabbitMQ log server.log + request.log
Alertas Fila cresce, consumidores caem Consumer lag, ISR shrinks

7. Critérios de escolha e cenários práticos

7.1. Quando escolher RabbitMQ

  • Microsserviços com comunicação assíncrona: notificações, tarefas em background
  • Roteamento complexo: mensagens precisam ser encaminhadas para destinos diferentes baseados em regras
  • Sistemas transacionais: pedidos, pagamentos, where cada mensagem precisa de confirmação
  • RPC síncrono: requisição-resposta entre serviços
Cenário ideal RabbitMQ:
- E-commerce: pedido → exchange "pedidos" → fila "processamento" + fila "notificacao"
- Consumidor de processamento confirma ACK → mensagem removida
- Consumidor de notificação rejeita → mensagem vai para DLQ para análise

7.2. Quando escolher Kafka

  • Pipelines de dados: ingestão de logs, eventos de clique, métricas de sensores
  • Analytics em tempo real: agregações, janelas temporais, detecção de anomalias
  • Replay de eventos: necessidade de reprocessar dados históricos
  • Múltiplos consumidores independentes: cada grupo lê o mesmo tópico do início
Cenário ideal Kafka:
- Plataforma de streaming: eventos de usuário → tópico "user_actions" (retenção 30 dias)
- Consumidor 1: análise de funnel (lê offset 0, processa todos os dados)
- Consumidor 2: detecção de fraude em tempo real (lê apenas novos eventos)
- Consumidor 3: backup para data lake (lê continuamente e armazena em S3)

7.3. Cenários híbridos: usando ambos em complemento

Sistemas avançados combinam as duas ferramentas: RabbitMQ para comunicação entre microsserviços (baixa latência, roteamento flexível) e Kafka para pipelines de dados (alto throughput, retenção).

Arquitetura híbrida:
- Frontend → RabbitMQ (pedidos, notificações, tasks)
- RabbitMQ → Worker (processa pedido) → RabbitMQ (resposta)
- Worker → Kafka (evento de pedido processado, log imutável)
- Kafka → Spark Streaming (análise de tendências)
- Kafka → Data Lake (armazenamento histórico)

8. Considerações finais e tendências

8.1. Custos operacionais e complexidade de manutenção

RabbitMQ é mais simples de operar (cluster pequeno, configuração declarativa). Kafka exige mais recursos: ZooKeeper (ou KRaft), tuning de JVM, gerenciamento de partições e monitoramento de lag. Em nuvem, serviços gerenciados (CloudAMQP, Confluent Cloud) reduzem a complexidade.

8.2. Alternativas modernas

  • Apache Pulsar: combina mensageria e streaming com separação entre compute e storage
  • NATS: ultra-leve, focado em alta performance e baixa latência
  • Redpanda: Kafka-compatível, escrito em C++, sem ZooKeeper, menor latência

8.3. Resumo: mensageria vs streaming como decisão arquitetural estratégica

A escolha entre RabbitMQ e Kafka não é técnica pura — é arquitetural. RabbitMQ resolve problemas de comunicação entre serviços com roteamento flexível e garantias de entrega. Kafka resolve problemas de dados em movimento com alto throughput e capacidade de replay. Projetos modernos frequentemente adotam ambos, posicionando cada ferramenta onde ela brilha.

A decisão deve considerar: volume de dados, necessidade de replay, complexidade de roteamento, latência tolerável e maturidade da equipe. Não existe "melhor" — existe "mais adequado ao contexto".

Referências