通过Rabbit DLQ延迟重新排队

时间:2018-01-30 22:49:37

标签: spring-cloud-stream spring-rabbitmq

我正在尝试按照here描述的模式设置一个延迟重播失败消息的队列。

我尝试尽可能地从文档中复制配置示例,但创建的死信队列本身并不绑定到DLX。我不清楚为什么不这样做。

我看到了另一个可能的解决方案,而不是依赖于默认行为,我尝试显式设置dlqDeadLetterExchange和dlqDeadLetterRoutingKey属性,以查看是否可以使其工作。我的配置如下所示:

rabbit:
  bindings:
    input:
      consumer:
        autoBindDlq: true
        bindingRoutingKey: my-routing-key
        dlq-ttl: 5000
        deadLetterExchange: dead-letter-exchange
        deadLetterQueueName: my-queue-dl
        dlqDeadLetterExchange: dead-letter-exchange
        dlqDeadLetterRoutingKey: my-queue-dl

这几乎可行。完成模式所需要做的就是手动将绑定添加到DLX,使用' my-queue-dl'来路由消息。将密钥路由回到我的队列'。但是,我还没有找到一种方法来记录spring-cloud-streams配置属性。有没有一种标准的方法可以做到这一点?某种' dlqDeadLetterExchangeBinding'配置?

1 个答案:

答案 0 :(得分:1)

请参阅Retry With the RabbitMQ Binder

  

autoBindDlq设置为true - 活页夹将创建DLQ;您可以选择在deadLetterQueueName

中指定名称      

dlqTtl设置为您想要在重新发送之间等待的退避时间

     

dlqDeadLetterExchange设置为默认交换 - 来自DLQ的过期消息将路由到原始队列,因为默认的deadLetterRoutingKey是队列名称(destination.group)

关键短语是“将dlqDeadLetterExchange设置为默认交换” - 该技术依赖于每个队列都绑定到默认交换的事实,路由密钥等于队列名称。

我刚刚再次测试它,它工作正常...

@SpringBootApplication
@EnableBinding(Sink.class)
public class So48531769Application {

    public static void main(String[] args) {
        SpringApplication.run(So48531769Application.class, args);
    }

    @StreamListener(Sink.INPUT)
    public void listen(String in, @Header(name = "x-death", required = false) List<?> death) {
        System.out.println(in + ":" + death);
        throw new RuntimeException("failed");
    }

}

spring:
  cloud:
    stream:
      bindings:
        input:
          consumer:
            max-attempts: '1'
          group: foo
      rabbit:
        bindings:
          input:
            consumer:
              autoBindDlq: 'true'
              dlq-dead-letter-exchange:
              dlq-ttl: '5000'

请注意,dlq-dead-letter-exchange属性未指定值 - 这意味着将过期消息路由到默认交换。

<强> input.foo

enter image description here

<强> input.foo.dlq

enter image description here