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.

Avançado 30 min 25 pontos Leitura 0%

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-service em 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

  1. 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()
  1. 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(),
        )
  1. 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.