嗨我的Rabbit监听器有问题导致异常无限循环(重新排队消息)。我的配置看起来:
@Bean(name = "defContainer")
public RabbitListenerContainerFactory containerFactory(ConnectionFactory connectionFactory, PlatformTransactionManager transactionManager){
SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory();
containerFactory.setConnectionFactory(connectionFactory);
containerFactory.setConcurrentConsumers(5);
containerFactory.setAcknowledgeMode(AcknowledgeMode.AUTO);
containerFactory.setTransactionManager(transactionManager);
containerFactory.setMessageConverter(messageConverterAmqp());
containerFactory.setDefaultRequeueRejected(false);
return new TxRabbitListenerContainerFactory(containerFactory);
}
其中transactionManager是postgre db上的事务的JpaTransactionManager。 TxRabbitListenerContainerFactory是我的工厂,它将setAlwaysRequeueWithTxManagerRollback设置为false:
public class TxRabbitListenerContainerFactory implements RabbitListenerContainerFactory {
private SimpleRabbitListenerContainerFactory factory;
public TxRabbitListenerContainerFactory(SimpleRabbitListenerContainerFactory factory) {
this.factory = factory;
}
@Override
public MessageListenerContainer createListenerContainer(RabbitListenerEndpoint endpoint) {
SimpleMessageListenerContainer container = factory.createListenerContainer(endpoint);
container.setAlwaysRequeueWithTxManagerRollback(false);
return container;
}
}
现在我有了以下列表:
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "topic.two", durable = "true"),
exchange = @Exchange(value = "topic.def", type = "topic", durable = "true"),
key = "letter.*"
), errorHandler = "rabErrorHandler", containerFactory = "defContainer")
@Transactional
public Motorcycle topicLetters(Motorcycle motorcycle) throws Exception{
motorcycle.setId(UUID.randomUUID().toString());
Testing testing = new Testing();
testingRepository.save(testing);
throwEx();
return motorcycle;
}
其中方法 throwEx(); 抛出未经检查的异常。 来自DB的数据被正确地回滚(未提交),但是消息不断被重新排队,在监听器中看到它:
@Bean
public RabbitListenerErrorHandler rabErrorHandler(){
return new RabbitListenerErrorHandler() {
@Override
public Object handleError(Message message, org.springframework.messaging.Message<?> message1, ListenerExecutionFailedException e) throws Exception {
System.out.println("FFFFFFFFFFF");
return null;
}
};
}
如何克服无限的loope,为什么会这样?
修改
日志:pasted logs
答案 0 :(得分:1)
在容器工厂上将defaultRequeueRejected
设置为false
。
要以编程方式决定何时重新排队,请将其保留在true
,并在您不希望重新排队时抛出AmqpRejectAndDontRequeueException
。
修改强>
有些东西没有加起来......
protected void prepareHolderForRollback(RabbitResourceHolder resourceHolder, RuntimeException exception) {
if (resourceHolder != null) {
resourceHolder.setRequeueOnRollback(isAlwaysRequeueWithTxManagerRollback() ||
RabbitUtils.shouldRequeue(isDefaultRequeueRejected(), exception, logger));
}
}
如果两个布尔都是假的,我们就不会重新排队。
答案 1 :(得分:0)
发现问题: 原因:由侦听器级别指定的errorHandler处理程序引起。在某些情况下,错误处理程序返回null - 这导致无限循环(而不是重新抛出异常和回滚事务)