Redis Pub/Sub vs Kafka
Redis Pub/Sub na prática
Integrando notification-service (Ruby) com analytics-service (Node) via Redis Pub/Sub.
Nesta aula você vai
- Publicar evento notification.sent no Redis Pub/Sub
- Consumir canal no analytics-service em Node
- Medir comportamento de evento efêmero quando subscriber cai
Redis Pub/Sub na prática
Objetivos
- Implementar fluxo real de publicação e assinatura entre dois serviços.
- Entender por que Pub/Sub não substitui mensageria durável.
- Adicionar logging útil para operação.
Pré-requisitos
- Redis ativo no Docker.
notification-service(Ruby/Sinatra) eanalytics-service(Node/Express) no ar.- Variável
REDIS_URLconfigurada.
Conceito
No Pub/Sub do Redis, a mensagem só chega em subscribers conectados no momento da publicação. Se o subscriber estiver offline, perdeu. Isso é ótimo para sinais operacionais de baixa criticidade.
Estrutura de arquivos
services/notification-service/
└── app/
├── app.rb
└── pubsub/publisher.rb
services/analytics-service/
└── src/
└── redis/
└── notifications-subscriber.js
Passo a passo
- Crie publisher no Ruby em
services/notification-service/app/pubsub/publisher.rb:
require "json"
require "redis"
require "securerandom"
require "time"
class Publisher
def initialize(redis_url)
@redis = Redis.new(url: redis_url)
end
def publish_notification_sent(customer_id:, channel:)
event = {
eventId: SecureRandom.uuid,
type: "notification.sent",
occurredAt: Time.now.utc.iso8601,
payload: {
customerId: customer_id,
channel: channel
}
}
@redis.publish("notifications.live", JSON.generate(event))
event
end
end
- Use no endpoint Sinatra (
services/notification-service/app/app.rb):
post "/notifications/send" do
body = JSON.parse(request.body.read)
event = publisher.publish_notification_sent(
customer_id: body.fetch("customerId"),
channel: body.fetch("channel")
)
status 202
JSON.generate(event)
end
- Crie subscriber no Node em
services/analytics-service/src/redis/notifications-subscriber.js:
import Redis from "ioredis";
import { incrementNotificationsSent } from "../store/metrics-store.js";
const subscriber = new Redis(process.env.REDIS_URL ?? "redis://redis:6379");
export async function startNotificationsSubscriber() {
await subscriber.subscribe("notifications.live");
subscriber.on("message", (channel, payload) => {
if (channel !== "notifications.live") return;
const event = JSON.parse(payload);
if (event.type !== "notification.sent") return;
incrementNotificationsSent();
console.log("notification.sent recebido", { eventId: event.eventId });
});
}
Como testar
docker compose up -d redis notification-service analytics-service
curl -s -X POST http://localhost:8004/notifications/send \
-H "Content-Type: application/json" \
-d '{"customerId":"c-22","channel":"email"}'
docker compose logs -f analytics-service
Pare o analytics-service, publique de novo e suba novamente: o evento publicado durante a queda não será entregue.
Dicas de projeto
- Nomeie canais com semântica de domínio (
notifications.live). - Mantenha payload pequeno no Pub/Sub.
- Se o evento for crítico, publique também no Kafka.
Erros comuns
- Assumir replay no Redis Pub/Sub.
- Não validar JSON de entrada no publisher.
- Ausência de logs com
eventIdpara rastreio.
Resumo
Você implementou um fluxo Pub/Sub real entre Ruby e Node, observando na prática a principal limitação: sem subscriber conectado, não há entrega.