Redis Pub/Sub vs Kafka
RPC vs eventos; filas vs Pub/Sub
Escolhendo padrão de integração certo com exemplos em Python, Kafka e Redis.
Nesta aula você vai
- Comparar RPC, eventos, fila e Pub/Sub com exemplos concretos
- Aplicar critérios de escolha por SLA e criticidade
- Documentar padrão por fluxo no e-commerce
RPC vs eventos; filas vs Pub/Sub
Objetivos
- Entender diferenças de acoplamento temporal e operacional.
- Evitar usar um padrão errado para o problema certo.
- Criar guideline simples para o time.
Pré-requisitos
- Conhecimento de REST, Kafka e Redis.
order-serviceem FastAPI e demais serviços disponíveis no monorepo.
Conceito
- RPC/HTTP: resposta imediata, acoplamento forte.
- Evento: comunicação assíncrona orientada a domínio.
- Fila: um consumidor por mensagem (escala de workers).
- Pub/Sub: vários consumidores recebem broadcast (geralmente efêmero no Redis).
Estrutura de arquivos
docs/architecture/integration-patterns.md
services/order-service/app/
├── clients/payment_client.py
└── events/order_events.py
services/analytics-service/src/redis/
└── notifications-subscriber.js
Passo a passo
- Exemplo RPC em Python (
services/order-service/app/clients/payment_client.py):
import httpx
class PaymentClient:
def __init__(self, base_url: str):
self.base_url = base_url
async def authorize(self, order_id: str, amount_cents: int) -> dict:
async with httpx.AsyncClient(timeout=2.5) as client:
response = await client.post(
f"{self.base_url}/payments/authorize",
json={"orderId": order_id, "amountCents": amount_cents},
)
response.raise_for_status()
return response.json()
- Exemplo evento em Kafka (
services/order-service/app/events/order_events.py):
import json
from aiokafka import AIOKafkaProducer
class OrderEventsPublisher:
def __init__(self, producer: AIOKafkaProducer):
self.producer = producer
async def publish_order_created(self, order_id: str, customer_id: str, amount_cents: int):
payload = {
"eventId": f"evt-{order_id}",
"type": "order.created",
"payload": {
"orderId": order_id,
"customerId": customer_id,
"amountCents": amount_cents,
},
}
await self.producer.send_and_wait(
"order.events",
key=order_id.encode(),
value=json.dumps(payload).encode(),
)
- Registre guideline em
docs/architecture/integration-patterns.md:
## Regras
- Use RPC quando a resposta for necessária na mesma transação do usuário.
- Use Kafka para eventos críticos com necessidade de retenção e replay.
- Use Redis Pub/Sub para sinais efêmeros de operação.
- Use fila com consumer group quando quiser paralelismo sem duplicidade de trabalho.
Como testar
RPC:
curl -s -X POST http://localhost:8002/orders \
-H "Content-Type: application/json" \
-d '{"customerId":"c-3","amountCents":8500}'
Evento Kafka e Pub/Sub:
docker compose logs -f order-service payment-service analytics-service
Dicas de projeto
- Defina padrão por caso de uso, não por preferência pessoal.
- Documente quem é dono de cada tópico/canal.
- Inclua idempotência em qualquer consumo assíncrono.
Erros comuns
- Usar RPC para fluxo com alta chance de indisponibilidade.
- Publicar evento sem
eventId. - Tratar Pub/Sub como substituto de fila durável.
Resumo
Você consolidou um guia prático para escolher entre RPC, eventos, fila e Pub/Sub, com exemplos reais no stack do monorepo.