O que são message queues e por que usar comunicação assíncrona

Desacoplamento temporal como base para sistemas resilientes

Message queues são componentes de middleware que armazenam mensagens produzidas por um sistema até que sejam consumidas por outro, permitindo que os dois sistemas operem de forma independente sem precisar estar disponíveis simultaneamente. Em comunicação síncrona, o produtor aguarda a resposta do consumidor — se o consumidor está lento ou indisponível, toda a cadeia para. Com message queues, o produtor publica a mensagem e segue sua execução, enquanto o consumidor processa no seu próprio ritmo quando estiver disponível. Esse desacoplamento temporal é fundamental para construir sistemas resilientes onde falhas em um componente não se propagam imediatamente para outros. Casos de uso clássicos incluem processamento de pedidos, envio de emails, geração de relatórios e qualquer operação que pode ser adiada sem impactar a experiência imediata do usuário.

Produtores e consumidores — como a fila conecta sistemas

A dinâmica de publicação e consumo de mensagens em diferentes topologias

O produtor é qualquer componente que publica mensagens na fila — um serviço web que recebeu um pedido, um sensor IoT que coletou uma leitura ou um job batch que gerou eventos a processar. O consumidor é o componente que lê e processa mensagens da fila, podendo ser um único worker dedicado ou um grupo de workers concorrentes que competem por mensagens. No modelo point-to-point, cada mensagem é entregue a exatamente um consumidor — ideal para distribuição de trabalho entre workers paralelos. No modelo publish-subscribe (pub/sub), cada mensagem é entregue a todos os subscribers registrados no tópico — ideal para notificar múltiplos sistemas sobre um mesmo evento sem que o produtor conheça todos os consumidores. RabbitMQ suporta ambos os modelos via exchanges, enquanto o Kafka usa o modelo pub/sub com consumer groups que permitem processamento paralelo dentro de um grupo.

Garantias de entrega — at most once, at least once, exactly once

Escolhendo o nível correto de garantia para cada caso de uso

At most once entrega a mensagem no máximo uma vez — se o consumidor falhar antes de processar, a mensagem é perdida. Adequado para métricas e logs onde perder dados ocasionalmente é aceitável e a duplicação seria mais problemática. At least once garante que a mensagem será entregue no mínimo uma vez, podendo ser entregue mais vezes em caso de retry após falha do consumidor — requer que o consumidor seja idempotente para lidar com duplicatas. Exactly once é a garantia mais forte e cara, garantindo que cada mensagem é processada exatamente uma vez mesmo sob falhas — implementada com transações distribuídas ou idempotent producers e consumers com deduplicação. A maioria dos sistemas de produção usa at least once com idempotência no consumidor como trade-off pragmático entre garantia e performance.

Filas FIFO vs não-ordenadas

Quando a ordem de processamento é crítica para a corretude do sistema

Filas FIFO (First In, First Out) garantem que mensagens são processadas na ordem em que foram produzidas — essencial para sequências de eventos onde a ordem importa, como transações financeiras de um mesmo cliente ou steps de um fluxo de aprovação. O trade-off do FIFO é performance e throughput reduzidos, pois ordenação global ou por partição impõe coordenação adicional entre consumidores concorrentes. O AWS SQS FIFO usa message group IDs para ordenação por grupo — mensagens do mesmo grupo são processadas em ordem, mas grupos diferentes são independentes, permitindo paralelismo entre grupos distintos. O Kafka ordena dentro de partições mas não entre elas — particionando por ID de cliente ou entidade, garante-se ordem por entidade enquanto se mantém paralelismo entre entidades diferentes.

Dead letter queues — tratando mensagens que falharam

Evitando que mensagens com erro travem o processamento da fila principal

Uma dead letter queue (DLQ) é uma fila separada para onde mensagens são movidas automaticamente após excederem o número máximo de tentativas de processamento, evitando que mensagens problemáticas bloqueiem ou ocupem indefinidamente a fila principal. Mensagens chegam na DLQ por diversas razões: payload malformado que causa exceção no consumer, violação de regra de negócio que torna a mensagem impossível de processar, ou dependência externa indisponível que impede o processamento. A DLQ deve ser monitorada ativamente — um acúmulo de mensagens indica um problema sistêmico que precisa de investigação, não apenas reprocessamento cego. Ferramentas de inspeção de DLQ permitem visualizar o conteúdo das mensagens, corrigir dados ou código do consumer, e re-enfileirar as mensagens para reprocessamento após a correção.

Backpressure — quando o consumer não aguenta o volume

Controlando o fluxo de mensagens para evitar sobrecarga do consumidor

Backpressure é o mecanismo pelo qual um consumidor comunica ao produtor que está sobrecarregado e não consegue processar mensagens no ritmo que estão chegando, evitando que a fila cresça indefinidamente até estourar memória ou disco. O prefetch count no RabbitMQ limita quantas mensagens o broker envia para cada consumer de uma vez — um consumer com prefetch de 10 não recebe mais mensagens até processar parte das que já tem, sinalizando implicitamente sua capacidade. Monitorar a profundidade da fila (queue depth) ao longo do tempo é a forma mais eficaz de detectar desequilíbrio entre produção e consumo — uma fila que cresce continuamente indica que mais consumidores são necessários ou que o processamento precisa ser otimizado. Auto scaling de consumers baseado em profundidade de fila é uma estratégia comum em cloud para absorver picos de carga sem superprovisionamento permanente.

Message queues vs event streaming

Escolhendo entre RabbitMQ, SQS e Kafka para diferentes padrões de uso

Message queues tradicionais como RabbitMQ e SQS são projetadas para entrega de mensagens individuais onde o estado da mensagem (pendente, processando, processada) é gerenciado pelo broker — após consumo confirmado, a mensagem é removida da fila. Event streaming com Kafka e Kinesis persiste eventos em um log imutável por tempo configurável (dias a semanas), permitindo que múltiplos consumidores independentes leiam o mesmo stream em velocidades diferentes e reprocessem eventos históricos. A escolha entre queue e stream depende do padrão de uso: para distribuição de trabalho entre workers concorrentes, use queue; para auditoria, replay, múltiplos consumidores independentes e análise de eventos em ordem, use stream. Sistemas complexos frequentemente usam ambos — Kafka como bus de eventos central e SQS/RabbitMQ para filas de trabalho de operações específicas.

Scaling de consumers horizontalmente

Aumentando throughput de processamento adicionando instâncias de consumer

A principal vantagem arquitetural de message queues é que consumers podem ser escalados horizontalmente sem qualquer mudança no produtor ou no broker — basta adicionar instâncias de consumer que automaticamente recebem parte do volume de mensagens. Em RabbitMQ, múltiplos consumers na mesma fila competem por mensagens em round-robin, e cada mensagem vai para apenas um consumer. No Kafka, consumers dentro do mesmo consumer group dividem as partições do tópico entre si — para 12 partições e 4 consumers, cada consumer recebe 3 partições; adicionar um quinto consumer redistribui as partições automaticamente. O número máximo de consumers paralelos em Kafka é limitado pelo número de partições do tópico, razão pela qual partições são provisionadas com margem para crescimento futuro. Kubernetes horizontal pod autoscaling com custom metrics baseadas em profundidade de fila via KEDA (Kubernetes Event-driven Autoscaling) automatiza o scaling de consumers.

Monitoramento de filas — profundidade, latência, erros

Métricas essenciais para operar filas de mensagens com confiabilidade

A profundidade da fila (messages ready para consumo) é a métrica mais importante, com alertas configurados para crescimento sustentado que indica capacidade insuficiente de consumers. A latência de mensagem — tempo entre publicação e início de processamento — indica o delay acumulado que afeta as operações downstream dependentes do processamento assíncrono. Taxa de mensagens na DLQ deve ter alerta de zero tolerância, pois qualquer mensagem na DLQ representa uma operação que falhou e pode precisar de intervenção manual. Em Kafka, consumer group lag — número de mensagens não consumidas por partition — é a métrica equivalente à profundidade de fila, monitorada por ferramentas como Burrow e disponível via Prometheus com kafka-exporter. Dashboards Grafana com essas métricas centralizadas permitem correlacionar aumento de profundidade de fila com deploys recentes, picos de tráfego ou falhas de consumidores específicos.

Conclusão — message queues como fundamento de resiliência

Comunicação assíncrona é um requisito para sistemas que precisam de alta disponibilidade

Message queues transformam dependências síncronas frágeis em integrações assíncronas resilientes, onde cada componente opera no seu próprio ritmo e falhas são contidas em vez de propagadas pela cadeia. A escolha do broker certo — RabbitMQ, SQS, Kafka ou outro — e da garantia de entrega adequada para cada caso de uso são decisões arquiteturais que impactam profundamente a complexidade operacional e a confiabilidade do sistema. Continue em: Fundamentos obrigatórios antes de produção.

Message Queues no YouTube

Conceitos de Message Queues

Message Queue

Componente de middleware que armazena mensagens entre produtor e consumidor, desacoplando os dois sistemas.

Dead Letter Queue

Fila para onde mensagens são movidas após excederem o número máximo de tentativas de processamento com falha.

Consumer Group

Grupo de consumers Kafka que divide as partições de um tópico entre si para processamento paralelo.

Backpressure

Mecanismo pelo qual o consumidor comunica sobrecarga, limitando o fluxo de mensagens para evitar colapso.

At Least Once

Garantia de entrega onde cada mensagem é entregue no mínimo uma vez, podendo haver duplicatas em falhas.

Consumer Lag

Número de mensagens não consumidas em uma partição Kafka, indicando o atraso do consumer em relação ao producer.

Message Queues no Instagram

@bytebytego

Reels — Sistemas e Arquitetura

@bytebytego

ByteByteGo no Facebook

Message Queues no X

@mjovanovictech

Como testar que sua API é resiliente e segura para produção real

Ver post completo no X →
@mjovanovictech

Implementando padrões de resiliência em .NET Core com exemplos reais

Ver post completo no X →
@mjovanovictech

Vertical Slice Architecture — organizando sistemas para escala

Ver post completo no X →
@mjovanovictech

5 anos com Clean Architecture — lições de sistemas em produção

Ver post completo no X →
@mjovanovictech

Design de APIs resilientes — retry, backoff e idempotência juntos

Ver post completo no X →
@mjovanovictech

Monolito vs Microsserviços — como escolher para cada contexto

Ver post completo no X →

O que dizem

Natalia Carvalho ★★★★★

A explicação sobre garantias de entrega e idempotência foi exatamente o que precisava para redesenhar nosso sistema de pedidos.

Samuel Pereira ★★★★★

KEDA para auto scaling de consumers baseado em consumer lag foi uma descoberta que mudou nossa operação no Kubernetes.

Daniela Fonseca ★★★★☆

Excelente comparação entre queue e streaming. Ajudou a escolher Kafka para eventos e SQS para filas de trabalho no mesmo sistema.