简体   繁体   中英

RabbitMQ DLX how to specify per-message TTL back to original queue?

I have a dead letter exchange which works as expected - when I nack a message it goes there:

@Override
public void onMessage(Message message, Channel channel) throws Exception {
    // How to specify when the message will be put back to the original queue?
    // This doesn't work.
    message.getMessageProperties().setExpiration("3000");
    channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
}

But what I cannot find is how to specify per-message when the message should be returned to the original queue. Please advise.

The expiration header is removed when the message is dead lettered. Secondly, messages do not automatically get sent back to your original queue from your deadletter queue.

It sounds like you want a retry system with per message wait times. This can be done but not the way you are doing it now.

The basic pattern is that you Ack your message and then send it to a "delay" exchange and queue. This queue sets it's dead letter exchange as your application's exchange. When a message arrives to the delay queue, it sits there until the message TTL is reached and gets dead lettered to your application exchange. However, this does not work when you have variable message expirations. Messages get dead lettered from the head of the queue so a message with a long expiration will block messages with shorter expirations behind it.

So you have various options to overcome this problem.

  1. Have a few standard delay exchanges to select from which have different queue based TTLs and don't set message expiration.
  2. Just before sending your message, declare a temporary delay exchange (that auto deletes) and queue (with a queue TTL that expires a few seconds after your message expires). Send your message and it will get dead lettered after the correct amount of time and then the exchange will auto delete and the queue will expire and be deleted. This could be very expensive if you have peaks of retries. However, if you name the temporary exchange and queue after the expiry time limit, then it will get reused by other messages with the same TTL being sent within the same period.
  3. NServiceBus has an ingenious technique using multiple delay exchanges and queues: https://docs.particular.net/nservicebus/rabbitmq/delayed-delivery

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM