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.