RabbitMQ DLX如何指定每个消息TTL回原始队列?

时间:2016-02-12 11:39:13

标签: java rabbitmq

我有一个死信交换,按预期工作 - 当我收到消息时,它会去那里:

@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);
}

但是我找不到的是当消息应该返回到原始队列时如何指定每条消息。请指教。

1 个答案:

答案 0 :(得分:0)

当邮件无效时,将删除过期标头。其次,消息不会自动从deadletter队列发送回原始队列。

听起来你想要一个每个消息等待时间的重试系统。这可以完成,但不是你现在这样做的方式。

基本模式是你确认你的消息,然后将其发送到"延迟"交换和排队。这个队列将它的死信交换设置为您的应用程序的交换。当一条消息到达延迟队列时,它就会一直存在,直到到达消息TTL并且在您的应用程序交换中被删除。但是,当您有可变的消息到期时,这不起作用。消息从队列的头部开始被删除,因此具有较长过期的消息将阻止其后面的消息较短的消息。

所以你有各种选择来克服这个问题。

  1. 有一些标准的延迟交换可供选择,它们具有不同的基于队列的TTL,并且不会设置消息到期。
  2. 在发送消息之前,声明临时延迟交换(自动删除)和队列(队列TTL在消息到期后几秒钟到期)。发送你的消息,它将在正确的时间后被删除,然后交换将自动删除,队列将过期并被删除。如果您有重试高峰,这可能会非常昂贵。但是,如果您在到期时间限制之后命名临时交换和队列,那么它将被同一时段内发送相同TTL的其他消息重用。
  3. NServiceBus使用多种延迟交换和队列的巧妙技术:https://docs.particular.net/nservicebus/rabbitmq/delayed-delivery