Spring RabbitTemplate setRetryTemplate& setRecoveryCallback被忽略了

时间:2017-02-03 18:42:44

标签: java spring spring-boot rabbitmq spring-rabbit

问题:经过一定数量的重试后,我想将消息发送到错误队列并从原始队列中消耗它。我想找到一个通用的解决方案,因为我处理了很多不同的消息,并根据他们提出的异常,我想采取不同的行动。如何设置RecoveryCallback以便Spring在maxRetries之后触发它?

我目前正在做什么
我尝试设置RetryTemplateRecoveryCallback。 当我运行应用程序并向test队列发布消息时,我希望EListener#receive中的处理失败3次,然后触发我配置的RecoveryCallback,然后根据上下文路由消息到特定的错误队列。

实际发生的事情 实际发生的是Spring Boot使用自己的RabbitAdmin初始化RabbitTemplate对象,因此不使用我配置的RabbitTemplate bean。

我有以下目录结构:

rabbit
  |___ EListener.java
  |___ Rabbit.java
test
  |___ Test.java

我在Rabbit.java

中有以下代码
@Configuration
public class Rabbit {

    @Autowired
    ConnectionFactory connectionFactory;

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setRetryTemplate(createRetryTemplate());
        rabbitTemplate.setRecoveryCallback(createRecoveryCallback());
        return rabbitTemplate;
    }

    createRecoveryCallback() // Omitted for brevity
    createRetryTemplate() // Omitted for brevity
}

EListener.java文件包含:

@Component
public class EListener {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "test", durable = "true"), exchange = @Exchange(value = "test", type = ExchangeTypes.TOPIC, durable = "true", autoDelete = "true"), key = "test"))
    public void receive(Message m) throws Exception {
        System.out.println(m);
        throw new Exception();
    }
}

Test.java包含:

@SpringBootApplication
@ComponentScan("rabbit")
public class Test {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Test.class).application().run(args);
    }
}

1 个答案:

答案 0 :(得分:1)

RetryTemplate添加RabbitTemplate是重试发布消息。

要在消费者方添加重试,您必须向侦听器container's advice chain添加重试拦截器。

由于您使用的是@RabbitListener,因此建议链会出现在listener container factory @Bean上,这意味着您必须自己声明一个,而不是依赖于引导创建的默认值。

无状态重试会在内存中重试; statefull retry重新排列消息;它需要一个messageId属性(或其他一些唯一标识消息的机制)。