System Design/04 - Cloud Design Patterns/Messaging2 min
Publisher-Subscriber
- Que problema isso resolve?
- Quando usar / quando NÃO usar?
- Qual o principal trade-off?
- Como isso falha em produção?
Conceito
O produtor publica num tópico e todos os inscritos recebem uma cópia. O produtor não sabe quem escuta.
┌→ inscrito A
publicador ──→ tópico ─┼→ inscrito B
└→ inscrito C
| Competing Consumers | Publisher-Subscriber | |
|---|---|---|
| Cada mensagem vai para | Um consumidor | Todos os inscritos |
| Objetivo | Escalar processamento | Distribuir o evento |
| Acoplamento | Fila conhecida | Produtor não conhece inscritos |
O padrão fan-out
Combinar os dois é o desenho canônico: um tópico entrega para várias filas, e cada fila tem seu grupo de consumidores concorrentes.
evento → tópico ┬→ fila-faturamento → workers
├→ fila-analytics → workers
└→ fila-notificacao → workers
Cada consumidor processa no próprio ritmo, com sua própria DLQ e seu próprio retry — a falha de um não afeta os outros.
Filtragem
Filtrar na inscrição (por atributo ou conteúdo) evita entregar tudo para todos e deixar cada consumidor descartar o que não interessa.
Trade-offs
O ganho é extensibilidade: adicionar um consumidor não exige tocar no produtor. É a propriedade que torna arquiteturas orientadas a evento evolutivas.
Os custos:
O fluxo fica invisível. Não existe um lugar no código onde se veja tudo que acontece quando um evento é publicado. Só o tracing distribuído reconstrói o quadro.
Tópico sem fila não é durável. Um sistema pub/sub puro entrega e esquece; se o inscrito está fora do ar, a mensagem se perde. Por isso o padrão de produção é tópico → fila por consumidor: o tópico distribui, a fila garante durabilidade.
Acoplamento migra para o schema. O produtor deixa de conhecer os consumidores e passa a estar preso ao formato do evento. Mudá-lo quebra consumidores que você não sabe que existem — daí versionamento e compatibilidade retroativa serem obrigatórios.
E o excesso de eventos cria cascatas: um consumidor publica outro evento, que dispara outro, e ninguém desenhou o ciclo resultante.
Exemplo prático
PedidoConfirmado publicado uma vez, consumido por quatro serviços: estoque reserva, faturamento emite nota, logística agenda coleta, marketing registra conversão.
O serviço de pedidos não conhece nenhum. Adicionar antifraude como quinto consumidor não exige alterar nem redeployar o produtor — é uma inscrição nova.
O que o desenho exige em troca: cada consumidor com sua fila e sua DLQ (senão a falha de faturamento afeta os outros), idempotência em todos (o evento será entregue duas vezes), e uma política clara de versionamento do evento — porque ele agora é um contrato público com quatro clientes.
Relacionado
Parte de Messaging · roadmap.sh/system-design