20 de Maio de 2025
Mensageria e filas
Quando usar fila no lugar de chamada síncrona, como funcionam os padrões principais e por que isso muda a arquitetura de produção.
Andrews Ribeiro
Founder & Engineer
5 min Intermediario Sistemas
Trilha
Trilha de system design para entrevistas
Etapa 8 / 19
O problema
Quando o sistema fica lento sob carga, muita gente tenta resolver só com mais instancia.
As vezes isso ajuda. Muitas vezes não.
Se o trabalho pesado continua no caminho síncrono da requisição, o usuário ainda espera, o timeout ainda existe e o pico ainda derruba o fluxo principal. Escalar a aplicação sem mudar o formato do trabalho e como contratar mais gente para uma fila em que cada pessoa ainda precisa fazer tudo na frente do cliente.
Fila muda esse formato.
Modelo mental
Fila e um buffer entre quem produz trabalho e quem executa trabalho.
O produtor diz “isso precisa acontecer”. O consumidor faz quando consegue. Eles não precisam estar vivos ao mesmo tempo e nem andar na mesma velocidade.
Isso resolve tres dores muito comuns:
- trabalho pesado no request
- pico de carga momentaneo
- dependência lenta ou instável
Pense assim:
- chamada direta = “faz isso agora e me responde”
- fila = “anota isso e processa no ritmo certo”
Nem tudo deve ir para fila. Mas tudo que pode sair do caminho principal sem quebrar a experiência merece ser analisado.
Quebrando o problema
Quando usar fila
Fila costuma fazer sentido quando:
- o usuário não precisa da resposta final imediatamente
- o trabalho e caro demais para ficar no request
- você quer absorver pico sem derrubar tudo
- mais de um consumidor precisa reagir ao mesmo evento
Exemplos classicos:
- envio de email
- geração de relatório
- processamento de imagem
- indexação de busca
- notificação
Se o usuário precisa da resposta na hora, talvez fila não seja a solução principal. Ou talvez você precise dividir o fluxo em duas partes: confirmação rápida agora, processamento completo depois.
At-least-once vs exactly-once delivery
Esses nomes assustam mais do que deveriam.
At-least-once significa: a mensagem sera entregue pelo menos uma vez. Na prática, ela pode aparecer de novo.
Exactly-once significa: o sistema promete que a mensagem sera processada uma unica vez do início ao fim. Na teoria e lindo. Na prática, end-to-end de verdade costuma ser caro, raro e cheio de condições.
Por isso, na maioria dos sistemas reais, você assume repetição possível e faz o consumidor aguentar isso sem estrago.
Idempotencia no consumidor
Se a mesma mensagem pode chegar duas vezes, o consumidor precisa saber repetir sem criar dano duplo.
Exemplos:
- não mandar o mesmo email de confirmação dez vezes
- não cobrar o mesmo pagamento duas vezes
- não criar o mesmo pedido de novo
Idempotencia, em linguagem simples, e isso: processar de novo e chegar no mesmo estado final.
Dead letter queue
Dead letter queue, ou fila de falha, e o lugar para onde vai a mensagem que falhou várias vezes.
Sem isso, você corre o risco de:
- reprocessar para sempre
- lotar a fila principal
- esconder erro serio no meio do ruido
Mensagem que foi para dead letter queue não morreu por capricho. Ela virou sinal de que aquele caso precisa de inspeção.
Kafka vs SQS vs RabbitMQ: quando cada um faz sentido
Não precisa decorar catalogo. Basta entender o encaixe.
- SQS faz muito sentido para trabalho assíncrono simples, com fila gerenciada e baixo atrito operacional.
- RabbitMQ costuma aparecer bem quando você precisa de roteamento mais detalhado e controle mais fino de mensageria tradicional.
- Kafka encaixa melhor quando o assunto parece fluxo de eventos em alta escala, retenção de mensagens e vários consumidores lendo o mesmo histórico.
Uma pergunta ajuda:
isso parece “tarefa para ser feita” ou “evento para vários consumidores observarem”?
Se parece tarefa, fila tradicional costuma ser suficiente. Se parece fluxo de eventos e histórico compartilhado, Kafka pode encaixar melhor.
Outra pergunta boa e esta:
eu preciso garantir que alguém execute isso, ou preciso que vários consumidores observem isso?
Ela costuma separar melhor fila de trabalho de stream de eventos do que comparação por marca.
Exemplo simples
Imagine um sistema de pedidos.
Quando o pagamento e aprovado, várias coisas podem acontecer:
- confirmar o pedido
- emitir nota
- mandar email
- atualizar estoque
- notificar sistema de analytics
Uma implementação ingênua faria tudo isso dentro do request.
Uma implementação melhor pode:
- confirmar o pagamento e salvar o pedido
- publicar um evento ou mensagem de
order_paid - deixar consumidores separados cuidarem do resto
Agora você ganhou:
- request mais rápido
- separação de responsabilidades
- reprocessamento controlado
- menos acoplamento entre fluxos
Mas também ganhou responsabilidade:
- lidar com duplicidade
- observar falha
- decidir ordem e garantia
Fila não remove complexidade. Ela move complexidade para um lugar mais administravel.
E isso só vale a pena quando você realmente precisa desse movimento. Se o fluxo e simples, síncrono e barato, fila pode só trocar clareza por operação desnecessaria.
Erros comuns
- Colocar fila em tudo por reflexo.
- Assumir que mensagem só chega uma vez.
- Não ter estratégia para falha repetida.
- Misturar evento com chamada RPC disfarcada.
- Achar que adicionar fila resolve regra de negócio mal definida.
Também vale cuidado com o extremo oposto: deixar tudo síncrono só porque “fica mais simples”. Em certo ponto, o sistema paga isso com timeout, pico instável e acoplamento demais.
Como um senior pensa
Quem tem mais experiência costuma fazer duas perguntas cedo:
o usuário precisa dessa resposta agora?
e
se essa mensagem chegar de novo, o que acontece?
Essas duas perguntas limpam boa parte da conversa.
Se a resposta pode vir depois, fila entra como candidata forte. Se repetição cria dano duplo, idempotencia vira obrigatoria.
Tem mais uma pergunta que costuma aparecer cedo na cabeça de quem já apanhou disso:
se o consumidor ficar para tras, o sistema degrada de forma aceitavel ou acumula problema invisível?
Essa pergunta puxa temas como backlog, backpressure e observabilidade, que sao parte real do custo da escolha.
O que o entrevistador quer ver
Em entrevista, mensageria não e só saber desenhar produtor e consumidor.
O entrevistador quer ver se você:
- sabe quando tirar trabalho do caminho principal
- entende entrega repetida como comportamento normal
- pensa em reprocessamento e fila de falha
- escolhe ferramenta pelo tipo de problema, não pelo nome famoso
Fila boa não e a que deixa o diagrama mais moderno. E a que protege o fluxo principal sem esconder o custo da complexidade.
Resumo rápido
O que vale manter na cabeça
- Fila desacopla produtor de consumidor e ajuda o sistema a absorver pico de carga.
- At-least-once significa que a mesma mensagem pode chegar de novo, por isso o consumidor precisa ser seguro para repetição.
- Dead letter queue guarda mensagem que falhou várias vezes e evita looping infinito.
- Kafka, SQS e RabbitMQ resolvem problemas parecidos por fora, mas com encaixes diferentes por baixo.
Checklist de pratica
Use isto ao responder
- Consigo explicar quando usar fila em vez de chamada direta?
- Sei o que muda no sistema quando a mensagem pode ser entregue mais de uma vez?
- Consigo desenhar produtor, fila, consumidor e tratamento de falha?
- Sei dizer quando um fluxo parece evento e quando parece trabalho pendente?
Você concluiu este artigo
Parte da trilha: Trilha de system design para entrevistas (8/19)
Próximo passo
Replicação e sharding sem mistério Próximo passo →Compartilhar esta página
Copie o link manualmente no campo abaixo.