System Design/04 - Cloud Design Patterns/Messaging2 min
Competing Consumers
- Que problema isso resolve?
- Quando usar / quando NÃO usar?
- Qual o principal trade-off?
- Como isso falha em produção?
Conceito
Vários consumidores lendo da mesma fila, cada mensagem processada por exatamente um deles. É como o processamento escala horizontalmente.
┌→ worker 1
fila ───┼→ worker 2 cada mensagem vai para UM worker
└→ worker 3
O broker garante a exclusividade por visibility timeout ou lease: enquanto um consumidor processa, a mensagem fica invisível para os demais. Se ele falhar sem confirmar, ela reaparece.
Diferente de Publisher-Subscriber, onde todos os inscritos recebem a mesma mensagem.
Trade-offs
O ganho é escala elástica e tolerância a falha: adicionar workers aumenta o throughput linearmente, e a morte de um worker não perde trabalho — a mensagem volta.
Os custos, todos consequência do processamento concorrente:
Ordem se perde. Com N workers, mensagens são processadas em paralelo e concluem fora de ordem. Se a ordem importa, o caminho é Sequential Convoy — ordem por chave, paralelismo entre chaves.
Duplicação acontece. Se o worker termina o trabalho mas morre antes de confirmar, a mensagem reaparece e será processada de novo. Idempotência não é opcional (Idempotent Operations).
Visibility timeout precisa caber no processamento. Curto demais e a mensagem reaparece enquanto ainda está sendo processada — dois workers no mesmo trabalho. Longo demais e uma falha real demora a ser detectada. Quando a duração é variável, o correto é estender o lease periodicamente durante o processamento.
Mensagem venenosa trava o ciclo: uma mensagem que sempre falha é reentregue indefinidamente e consome capacidade. A DLQ existe exatamente para isso, e uma fila sem DLQ é uma fila incompleta.
Exemplo prático
Uma fila com 10 mil mensagens e 5 workers, cada um processando uma por segundo.
5 workers → ~33 minutos
20 workers → ~8 minutos
O throughput escala com o número de consumidores, sem nenhuma coordenação entre eles — essa é a virtude do padrão.
O detalhe que decide o desenho: com processamento de duração variável (de 1 s a 5 min), um visibility timeout fixo é sempre errado. Curto, duplica; longo, atrasa a recuperação. A solução é o worker renovar o lease enquanto trabalha — e desistir se o trabalho exceder um teto absoluto.
Relacionado
Parte de Messaging · roadmap.sh/system-design