问题:经过一定数量的重试后,我想将消息发送到错误队列并从原始队列中消耗它。我想找到一个通用的解决方案,因为我处理了很多不同的消息,并根据他们提出的异常,我想采取不同的行动。如何设置RecoveryCallback
以便Spring在maxRetries
之后触发它?
我目前正在做什么
我尝试设置RetryTemplate
和RecoveryCallback
。
当我运行应用程序并向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);
}
}
答案 0 :(得分:1)
向RetryTemplate
添加RabbitTemplate
是重试发布消息。
要在消费者方添加重试,您必须向侦听器container's advice chain添加重试拦截器。
由于您使用的是@RabbitListener
,因此建议链会出现在listener container factory @Bean
上,这意味着您必须自己声明一个,而不是依赖于引导创建的默认值。
无状态重试会在内存中重试; statefull retry重新排列消息;它需要一个messageId属性(或其他一些唯一标识消息的机制)。