根据doc,defaultRequeueRejected的默认值为true,但查看代码似乎是错误的。我不确定我是否遗漏了任何东西,或者我们必须在SimpleRabbitListenerContainerFactory.java中更改它
修改
示例代码,在将消息放入测试队列后,我预计它会因为失败而保持在队列中,但它会将其丢弃。我希望重试消息,所以我在容器工厂配置它,如果它在重试后失败,我希望它回到队列中。我相信我在这里缺乏理解。
@SpringBootApplication
public class MsgRequeExampleApplication {
public static void main(String[] args) {
SpringApplication.run(MsgRequeExampleApplication.class, args);
}
@Bean(name = "myContainerFactory")
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setMissingQueuesFatal(false);
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(500);
factory.setAdviceChain(new Advice[] { org.springframework.amqp.rabbit.config.RetryInterceptorBuilder.stateless()
.maxAttempts(2).backOffPolicy(backOffPolicy).build() });
return factory;
}
@RabbitListener(queues = "test", containerFactory = "myContainerFactory")
public void processAdvisory(Message message) throws MyBusinessException {
try{
//Simulating exception while processing message
String nullString=null;
nullString.length();
}catch(Exception ex){
throw new MyBusinessException(ex.getMessage());
}
}
public class MyBusinessException extends Exception {
public MyBusinessException(String msg) {
super(msg);
}
}
}
答案 0 :(得分:4)
SimpleMessageListenerContainer
JavaDocs中有一个很好的描述:
/**
* Set the default behavior when a message is rejected, for example because the listener
* threw an exception. When true, messages will be requeued, when false, they will not. For
* versions of Rabbit that support dead-lettering, the message must not be requeued in order
* to be sent to the dead letter exchange. Setting to false causes all rejections to not
* be requeued. When true, the default can be overridden by the listener throwing an
* {@link AmqpRejectAndDontRequeueException}. Default true.
* @param defaultRequeueRejected true to reject by default.
*/
public void setDefaultRequeueRejected(boolean defaultRequeueRejected) {
this.defaultRequeueRejected = defaultRequeueRejected;
}
对你有意义吗?
<强>更新强>
要在重试耗尽后重新排队,您需要在MessageRecoverer
上使用以下代码配置一些自定义RetryInterceptorBuilder
:
.recoverer((message, cause) -> {
ReflectionUtils.rethrowRuntimeException(cause);
})
这样会将异常抛出到侦听器容器,并根据其defaultRequeueRejected
消息将被重新排队。