Arquitetura com filas para equipes pequenas: async sem mistério
Uma fila ajuda quando a requisição deve ser aceita logo, mas o trabalho demora, depende de sistema instável ou precisa de vazão controlada. Ela também adiciona outro runtime, resultado atrasado e entrega duplicada. Equipes pequenas devem incluir fila para remover um gargalo concreto, não só porque diagramas ficam mais bonitos.
Publicado em 28 de setembro de 202614 min de leituraProcessamento assíncrono e operação
Separe aceite da requisição e conclusão do negócio
Persista a intenção, publique o trabalho, processe com segurança e exponha o estado final
1 / RequisiçãoValide o chamador e a intenção de negócio.
2 / PersistirGrave operação e evento outbox juntos.
3 / EntregarDispatcher publica mensagem durável.
4 / ConsumirWorker reserva, processa e registra resultado.
5 / ObservarCliente consulta estado; operação vê idade/falhas.
Retorne ID do job e estado explícito “aceito/em andamento”, não um sucesso falso sugerindo que relatório, e-mail ou pagamento terminou. Defina como consultar, o que cancelamento significa e se falha repete sozinha ou exige análise humana.
Escolha trabalho que ganha com async
Carga
Fila ajuda quando...
Ainda é preciso definir...
Efeitos de webhook
Provedor espera confirmação rápida.
Assinatura, aceite durável, dedupe e ordenação.
Relatórios e exportações
Demora ou exige mais recursos.
Visibilidade, cancelamento, expiração do arquivo e progresso.
Sincronização de API externa
Limite ou indisponibilidade não deve bloquear o usuário.
Backoff, cotas, atualidade e reconciliação.
Notificações
Entrega pode atrasar sem alterar transação confirmada.
Preferência, duplicatas, falha do provedor e estado visível.
Mantenha síncrono o que precisa de resposta autoritativa imediata e cabe no orçamento da requisição. Fila não acelera algoritmo caro; muda quem espera e como a espera é observada.
Feche a lacuna entre banco e fila
Bug comum: gravar pedido e cair antes de publicar mensagem. Outbox transacional grava estado do negócio e evento pendente numa transação; dispatcher publica e marca entrega. Consumidor ainda precisa tolerar duplicatas: processo pode cair após publicar e antes de marcar sucesso. Para risco menor, tabela de jobs persistida pode bastar, desde que tenha recuperação explícita.
Assuma entrega ao menos uma vez
Muitas filas podem entregar de novo após timeout ou crash. Dê ID estável à operação, aplique unicidade ou registro de idempotência e torne efeitos externos idempotentes. Confirme/remova mensagem só após conclusão durável. Se o worker passar do visibility timeout/lease, estenda-o ou divida em etapas limitadas para evitar processamento paralelo.
Retries precisam de limite e motivo
Repita falhas transitórias de timeout, rate limit e dependência com backoff exponencial e jitter. Não repita para sempre entrada malformada ou falha permanente de autorização. Limite tentativas e duração; depois mova para dead letter/quarentena com motivo e correlação. Ofereça replay seguro que preserve ID lógico e registre nova tentativa.
Backpressure é sinal de produto
Limite profundidade ou idade e decida o que o usuário vê com backlog crescente. Escale consumidor só até downstream suportar. Se chegada exceder processamento, mais workers sobrecarregam banco ou parceiro. Use concorrência, lote, justiça por cliente e controle do produtor. Idade da fila costuma explicar mais que profundidade porque tarefas variam.
Faça a observabilidade acompanhar o job
Meça aceite, fila, início, retry, conclusão e falha com horário e ID de correlação. Alerte sobre mensagem mais antiga, retries, DLQ, erro do consumidor e throttle de dependência. Minimize payload e remova dado sensível dos logs. Retenção de mensagem concluída e histórico de job são políticas distintas.
Comece pelo menor desenho operável
Fila gerenciada, um worker e tabela de estado do job muitas vezes bastam. Evite cluster de broker e orquestração própria antes de haver carga ou isolamento que justifique. Documente dono, deploy/rollback, mensagem venenosa, replay autorizado e indisponibilidade do provedor da fila.
Em resumo
Filas separam aceite de conclusão, mas transferem complexidade para retries, duplicatas, visibilidade e operação. Persista intenção, publique com confiabilidade, processe com idempotência, limite retries e exponha estado. Adicione fila para um problema real de usuário ou confiabilidade e mantenha a operação pequena o bastante para a equipe cuidar.