NATS JetStream: mensageria persistente e rápida para sistemas distribuídos
1. Introdução ao NATS e ao JetStream
NATS é um sistema de mensageria open source conhecido por sua simplicidade, alto desempenho e latência extremamente baixa. Originalmente criado pela Cloud Foundry e posteriormente mantido pela CNCF, o NATS Core oferece comunicação publish/subscribe e request/reply com entrega "at-most-once". Essa simplicidade, porém, limitava seu uso em cenários que exigiam persistência, garantias de entrega mais fortes e replay de mensagens.
O JetStream surge como uma extensão nativa do NATS para superar essas limitações. Construído sobre o mesmo protocolo leve, o JetStream adiciona:
- Persistência baseada em arquivo com replicação via Raft
- Garantias de entrega at-least-once e exactly-once
- Replay de mensagens e filas duráveis
- Armazenamento de objetos e chave-valor
Diferente de soluções como Kafka, o JetStream mantém a simplicidade operacional do NATS, sendo executado como um único binário e configurado via API REST ou CLI.
2. Conceitos Fundamentais do JetStream
Streams
Streams são sequências ordenadas e persistentes de mensagens. Cada stream pertence a um ou mais subjects (tópicos) e armazena mensagens conforme políticas de retenção configuradas.
# Criando um stream via CLI
nats stream add ORDERS --subjects "orders.>" --storage file --retention limits --max-msgs 1000000 --max-age 365d
Consumers
Consumers são assinantes de streams com estado próprio. Existem dois modos:
- Push consumer: o servidor envia mensagens para um endpoint (útil para microsserviços)
- Pull consumer: o cliente solicita mensagens sob demanda (útil para filas de trabalho)
# Criando um consumer pull
nats consumer add ORDERS WORKER --pull --ack explicit --deliver all --max-deliver 5
Stores Adicionais
Além de streams, o JetStream oferece:
- Object Store: armazenamento de arquivos grandes (até GBs)
- Key-Value Store: armazenamento consistente com operações atômicas
# Criando uma KV store
nats kv add CONFIG --history 5
nats kv put CONFIG db_host localhost
3. Arquitetura e Modelo de Persistência
O JetStream utiliza um modelo de armazenamento baseado em arquivos com suporte a replicação síncrona via Raft. As principais estratégias de retenção são:
- Limits: baseado em idade, tamanho ou quantidade máxima de mensagens
- Interest: mantém mensagens até que todos os consumidores as reconheçam
- Work Queue: mensagens são removidas após o primeiro reconhecimento
A desduplicação é feita através de um ID único (Nats-Msg-Id) e uma janela configurável (dedup window), garantindo que mensagens duplicadas não sejam armazenadas.
# Configurando desduplicação
nats stream add ORDERS --subjects "orders.>" --dedup 2m
4. Garantias de Entrega e Confiabilidade
O JetStream oferece três níveis de garantia:
- At-least-once: com acknowledgments explícitos, mensagens são reentregues se não confirmadas
- Exactly-once: combinando IDs de mensagem com dedup window e idempotência do consumidor
- At-most-once: modo fire-and-forget (padrão NATS Core)
Para mensagens que excedem o limite de entregas, o JetStream suporta Dead Letter Queue (DLQ):
# Consumer com DLQ
nats consumer add ORDERS WORKER --max-deliver 3 --backoff 5s,10s,30s --dlq DLC_ORDERS
5. Performance e Escalabilidade
O JetStream foi projetado para alto throughput horizontal. Streams podem ser particionados (sharded) e consumidores paralelos processam partições independentes.
Principais características de performance:
- Latência média: 1-5ms (vs 10-50ms do Kafka)
- Throughput: até 1 milhão de mensagens/segundo por nó
- Compressão: suporte nativo a compressão LZ4 e Snappy
- Cache de índices: índices em memória para acesso rápido a mensagens
# Stream particionado (sharded)
nats stream add ORDERS --subjects "orders.>" --max-streams 4
Comparado ao Kafka, o JetStream oferece latência 5-10x menor e operação mais simples (sem Zookeeper). Comparado ao RabbitMQ, oferece throughput 3-5x maior e melhor escalabilidade horizontal.
6. Casos de Uso e Padrões de Integração
Event Sourcing e CQRS
Streams persistentes permitem armazenar eventos de domínio e reconstruir estado de agregados via replay.
# Replay de eventos
nats stream replay ORDERS --since "2024-01-01" --until "2024-06-30"
Filas de Trabalho (Work Queues)
Pull consumers com acknowledgments garantem processamento confiável de tarefas assíncronas.
# Consumidor pull em Python
import asyncio
from nats import connect
async def worker():
nc = await connect()
js = nc.jetstream()
consumer = await js.pull_subscribe("orders.>", "WORKER")
while True:
msgs = await consumer.fetch(10, timeout=5)
for msg in msgs:
print(f"Processando: {msg.data}")
await msg.ack()
Bridge com Outros Sistemas
O NATS suporta bridges nativas para Kafka, MQTT e WebSocket, permitindo integração com ecossistemas existentes.
# Configurando bridge NATS-Kafka
nats bridge add KAFKA_BRIDGE --type kafka --brokers localhost:9092 --topic orders
7. Operação, Monitoramento e Boas Práticas
Gerenciamento via CLI e API
# Listar streams
nats stream list
# Verificar lag de consumidor
nats consumer info ORDERS WORKER
# Monitorar em tempo real
nats stream stats ORDERS --wait
Métricas Chave
- Lag: diferença entre última mensagem publicada e último offset consumido
- Throughput: mensagens por segundo (publicação e consumo)
- Utilização de disco: espaço ocupado por streams e índices
- Replicação: estado Raft (líder, seguidor) e latência de replicação
Boas Práticas
- Configurar políticas de retenção adequadas para evitar crescimento infinito
- Usar dedup window para garantir idempotência em produtores
- Monitorar lag com alertas para detectar consumidores lentos
- Fazer backup regular dos diretórios de dados JetStream
- Testar failover em clusters com replicação R3 (3 nós)
# Backup de stream
nats stream backup ORDERS --directory /backup/orders_2024
O JetStream representa a evolução do NATS para sistemas distribuídos que exigem persistência e confiabilidade sem abrir mão da simplicidade e performance. Seja para event sourcing, filas de trabalho ou integração entre microsserviços, o JetStream oferece uma solução madura e eficiente.
Referências
- NATS JetStream Official Documentation — Documentação completa sobre conceitos, configuração e operação do JetStream
- NATS by Example: JetStream — Tutoriais práticos com exemplos de código para streams, consumers e KV stores
- JetStream Architecture Deep Dive — Artigo técnico detalhando o modelo de persistência, replicação Raft e estratégias de retenção
- NATS JetStream vs Kafka: Performance Comparison — Comparação de latência, throughput e complexidade operacional entre JetStream e Kafka
- NATS Surveyor: Monitoring Tool — Ferramenta open source para monitoramento de métricas JetStream (lag, throughput, utilização de disco)