trilha

System Design/02 - Componentes/Asynchronism2 min

Message Queues

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Um buffer durável entre produtor e consumidor. O produtor publica e segue; o consumidor lê quando pode.

Garantias de entrega

Garantia Significa Custo
At-most-once 0 ou 1 vez — pode perder Nenhum
At-least-once 1 ou N vezes — pode duplicar Exige Idempotent Operations
Exactly-once Exatamente 1 vez Caro; quase sempre é at-least-once + dedup

Na prática, quase todo sistema usa at-least-once + consumidor idempotente.

Modelos

Modelo Quem recebe
Point-to-point (fila) Um consumidor por mensagem — trabalho dividido
Pub/sub (tópico) Todos os inscritos (Publisher-Subscriber)

Mecânica essencial

  • ACK explícito: a mensagem só some depois da confirmação. Sem ACK, ela reaparece.
  • Visibility timeout / lease: janela em que a mensagem fica invisível para outros. Curta demais → processamento duplicado.
  • DLQ: após N tentativas, isola a mensagem venenosa para não travar a fila.
  • Retenção: por quanto tempo a mensagem sobrevive não consumida.

Broker vs log

Broker (RabbitMQ, SQS) Log distribuído (Kafka)
Após consumir Mensagem some Permanece até expirar
Replay Não Sim
Consumidores independentes Concorrem Cada um com seu offset
Ordem Por fila Por partição

Trade-offs

Fila adiciona latência e complexidade em troca de resiliência e desacoplamento. A resposta deixa de ser síncrona, e o sistema precisa devolver o resultado depois (Returning Results).

Ordenação é o trade-off mais caro: garantir ordem global serializa o processamento e mata o paralelismo. A saída usual é ordenar por chave — ordem estrita dentro do cliente, paralelismo entre clientes.

E o já dito: fila mascara subcapacidade. Monitorar tamanho e idade da fila importa mais que CPU do consumidor — é a métrica que revela o déficit antes do estouro.

Exemplo prático

Upload de vídeo. A API grava o arquivo, publica {videoId} na fila e responde 202 Accepted em 200 ms. Um pool de workers consome e transcodifica, o que leva minutos.

O que a fila comprou: o usuário não espera; um pico de mil uploads só engorda a fila; se um worker morre no meio, a mensagem volta e outro pega.

O que ela cobrou: o cliente precisa descobrir quando terminou, o worker precisa ser idempotente (a mensagem pode voltar depois de já ter transcodificado), e alguém precisa vigiar a fila para notar quando ela cresce sem parar.

Relacionado


Parte de Asynchronism · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas