O RabbitMQ não suporta nativamente mensagens atrasadas. Atualmente, as principais implementações incluem o uso de um sistema de troca de mensagens não entregues (dead-letter exchange) + esquema de tempo de vida da mensagem (message TTL) ou o plugin rabbitmq-delayed-message-exchange.
Casos de uso para filas atrasadas
- Cenários em que existem requisitos de janela de tempo para produção e consumo de mensagens. Por exemplo, em transações de comércio eletrônico, há um cenário em que os pedidos são encerrados se o pagamento não for concluído dentro de um período de tempo limite. Nesse caso, uma mensagem atrasada é enviada quando o pedido é criado. Essa mensagem será entregue ao consumidor 30 minutos depois, e o consumidor precisa verificar se o pedido correspondente foi pago. Se o pagamento não for concluído, o pedido é encerrado; se o pagamento for concluído, a mensagem é ignorada.
- Cenários em que tarefas atrasadas são acionadas por mensagens. Por exemplo, enviar mensagens de lembrete para usuários após um período de tempo especificado.
Esquema de troca de mensagens não entregues + message TTL
A ideia principal desse método é criar uma fila sem consumidores e utilizar o tempo de expiração da mensagem (TTL). Quando uma mensagem expira, ela se torna uma mensagem não entregue, que é encaminhada para uma troca de mensagens não entregues e, em seguida, para uma fila de mensagens não entregues, que pode ser consumida.
Nesse método, o tempo de expiração da mensagem serve como o tempo de atraso da mensagem. Por exemplo, se o TTL da mensagem for configurado para 30 segundos e não houver consumidores para a fila, a mensagem expirará após 30 segundos e se tornará uma mensagem não entregue, que será manipulada pela fila de mensagens não entregues.
Para implementar esse método, as propriedades precisam ser configuradas conforme descrito nos seguintes dois tutoriais:
Solução do plugin de mensagens atrasadas
1. Instalando o plugin
Repositório do GitHub rabbitmq-delayed-message-exchange:
https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases
Baixe o arquivo rabbitmq_delayed_message_exchange-3.8.9-0199d11c.ez na seção de assets da página de lançamento no GitHub e coloque o arquivo no diretório de plugins do RabbitMQ (diretório de plugins).
Nota: O número da versão pode ser diferente do deste tutorial. Se o seu RabbitMQ for a versão mais recente, simplesmente escolha a versão mais recente do plugin.
2. Ativando o plugin
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
3. Definindo a troca de mensagens
Configure as propriedades personalizadas da troca de mensagens usando x-delayed-type para suportar o envio de mensagens atrasadas.
props := make(map[string]interface{})
// Parâmetro chave para suportar o envio de mensagens atrasadas
props["x-delayed-type"] = "direct"
// Declare a troca de mensagens
err = ch.ExchangeDeclare(
"delay.queue", // Nome da troca
"fanout", // Tipo da troca
true, // Durável
false,
false,
false,
props, // Definir propriedades
)
4. Enviando mensagens atrasadas
Configure o tempo de atraso da mensagem usando o cabeçalho da mensagem (x-delay).
msgHeaders := make(map[string]interface{})
// Configure o tempo de atraso da mensagem usando o cabeçalho da mensagem, em milissegundos
msgHeaders["x-delay"] = 6000
err = ch.Publish(
"delay.queue", // Nome da troca
"", // Parâmetro de roteamento
false,
false,
amqp.Publishing{
Headers: msgHeaders, // Definir cabeçalhos da mensagem
ContentType: "text/plain",
Body: []byte(body),
})
Nota: Se estiver usando o serviço de Fila de Mensagens RabbitMQ da Alibaba Cloud diretamente, você pode definir o tempo de atraso usando o atributo do cabeçalho da mensagem (delay) sem instalar o plugin. A Alibaba Cloud já estendeu o RabbitMQ para esse fim.