我已经建立了Apache骆驼,其中我从一个队列中使用消息,并对它进行某种操作,然后将其传输到另一个队列中。
现在,如果出现异常,那么我希望它应该回滚,然后在6次尝试将其发送到死信队列后,当前回滚发生5-6次,但我的消息未传输到死信队列。
这是怎么回事-> Queue1->(消耗)->操作(引发异常)->回滚->再次Queue1->(消耗)->操作(引发异常)->回滚-> ... 5-6次,然后我的消息丢失了
我不知道消息的去向以及消息丢失的原因,并且从我的Active MQ GUI中可以看到消息已出队。
@Bean
public RedeliveryPolicy redeliveryPolicy() {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setMaximumRedeliveries(2);
redeliveryPolicy.setMaximumRedeliveryDelay(10000);
redeliveryPolicy.setRedeliveryDelay(10000);
return redeliveryPolicy;
}
---------------------Route extends SpringRouteBuilder-------------------
onException(MyException.class)
.markRollbackOnly()
.redeliveryPolicy(redeliveryPolicy)
.useExponentialBackOff()
.handled(true)
from("jms:queue:Queue1")
.process(new Processor(){
public void process(Exchange ex){
throw new RuntimeException();
}
}).to("jms:queue:myQueue)
答案 0 :(得分:1)
我认为有多个问题。
markRollbackOnly
停止邮件。在此语句之后,不再进行路由。 这就是为什么您的RedeliveryPolicy
和onException
其余路线被完全忽略的原因。您配置了2次重新交付尝试,但您编写了5次(ActiveMQ的默认重新交付尝试)。
要解决此问题,请将markRollbackOnly
移至onException
路线的末尾
由于在发生错误时将其丢失,因此事务配置存在问题。配置Camel的ActiveMQ组件在使用时使用本地JMS事务。
@Bean(name = "activemq")
@ConditionalOnClass(ActiveMQComponent.class)
public ActiveMQComponent activeMQComponent(ConnectionFactory connectionFactory) {
ActiveMQComponent activeMQComponent = new ActiveMQComponent();
activeMQComponent.setConnectionFactory(connectionFactory);
activeMQComponent.setTransacted(true);
activeMQComponent.setLazyCreateTransactionManager(false);
return activeMQComponent;
}
在这种情况下,实际上您可以删除onException
路由,因为交付是由JMS代理完成的,因此您必须在JMS连接上配置重新交付设置。如果已配置的重新交付已用尽,并且消息仍然产生回滚,则将其移至DLQ。
使用附加的onException
路线时要注意,因为这是纯骆驼。 Camel错误处理程序不会在路由级别上重新交付,而是在处理器级别上重新交付。因此,如果同时配置代理和骆驼重新交付,则可以将它们相乘。