Programação · Arquitetura · Backend
O que é uma fila de mensagens?
Quando uma parte da sua app precisa de passar trabalho a outra - enviar um email, redimensionar uma imagem, cobrar um cartão - fazê-lo em linha faz o utilizador esperar e liga fortemente as duas partes. Uma fila de mensagens é a solução padrão: um buffer no meio onde um serviço deixa uma tarefa e outro a recolhe mais tarde. Este guia explica o que é uma fila de mensagens, como producers e consumers a usam, e quando precisa mesmo de uma.
A ideia central: producer, fila, consumer
Uma fila de mensagens fica entre o código que cria o trabalho e o que o executa. Um producer coloca uma mensagem - uma pequena unidade de dados que descreve uma tarefa - na fila. Um consumer retira as mensagens e processa-as. A fila guarda cada mensagem até ser tratada, normalmente por ordem de chegada. O ponto-chave: o producer não espera pelo consumer e nem precisa de saber quem ele é.
Porquê usar uma: desacoplamento, buffer, resiliência
Uma fila traz várias coisas ao mesmo tempo. Desacopla producer e consumer, para os construir, implementar e escalar em separado. Amortece picos: se chegarem 10.000 registos de uma vez, fazem fila em vez de sobrecarregar o worker. Acrescenta resiliência, porque se um consumer estiver em baixo as mensagens esperam em vez de se perderem. E torna o trabalho assíncrono - devolve o controlo ao utilizador de imediato e faz a parte lenta em segundo plano.
Fila vs publicação/subscrição
Há dois padrões comuns. Numa simples fila de trabalho, cada mensagem é entregue a exatamente um consumer - ideal para distribuir tarefas por um conjunto de workers. Na publicação/subscrição (pub/sub), uma mensagem é difundida a cada subscritor interessado - ideal para eventos a que várias partes do sistema reagem. Muitos brokers suportam ambos, usando a ideia de exchanges ou topics para decidir quem recebe uma cópia.
As garantias de entrega, com honestidade
As filas descrevem o esforço que fazem para entregar uma mensagem: no máximo uma vez (rápido, pode perder), pelo menos uma vez (pode entregar duas vezes) e exatamente uma vez (a mais difícil, muitas vezes matizada na prática). A maioria dos sistemas reais oferece pelo-menos-uma-vez, o que significa que os seus consumers devem ser idempotentes - processar a mesma mensagem duas vezes não deve causar dano. Os consumers costumam confirmar uma mensagem só depois de a terminarem; se um falhar antes de confirmar, a mensagem é reentregue. As mensagens que falham repetidamente vão para uma fila de mensagens mortas para inspeção.
Brokers comuns: RabbitMQ, Kafka, Redis
Poucas ferramentas dominam. O RabbitMQ é um broker clássico com encaminhamento flexível (fala AMQP). O Apache Kafka é um log durável de alto débito: retém as mensagens para que os consumers possam reproduzir um fluxo, o que se adequa a pipelines de eventos e analítica. O Redis oferece filas e streams leves e muito rápidos, embora menos duráveis por omissão. Na cloud, opções geridas como AWS SQS e Google Pub/Sub retiram o peso operacional. Escolha pela necessidade: RabbitMQ para encaminhamento, Kafka para fluxos reproduzíveis de grande volume, Redis para o simples e rápido.
Quando não precisa de uma
Uma fila é uma peça móvel que tem de correr e monitorizar. Se o trabalho é rápido e quem chama precisa mesmo do resultado de imediato, uma chamada de função direta ou uma escrita em base de dados é mais simples. Recorra a uma fila de mensagens quando precisar de jobs em segundo plano assíncronos, quiser absorver picos de carga, ou precisar de desacoplar serviços que não deveriam depender diretamente um do outro - as mesmas razões pelas quais talvez já ponha serviços atrás de um proxy reverso ou de um balanceador de carga.
Conclusão
Uma fila de mensagens é um buffer entre serviços: os producers deixam trabalho, os consumers recolhem-no, e os dois ficam desacoplados enquanto a carga é suavizada. Use uma simples fila de trabalho para distribuir tarefas, pub/sub para difundir eventos, conte com entrega pelo-menos-uma-vez (torne os consumers idempotentes), e recorra a RabbitMQ, Kafka, Redis ou uma fila cloud gerida quando precisar de processamento assíncrono fiável.