将消息回滚到Dead Letter Queue-Apache Camel

时间:2018-08-28 09:00:49

标签: apache-camel jms activemq

我已经建立了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)

1 个答案:

答案 0 :(得分:1)

我认为有多个问题。

  1. markRollbackOnly停止邮件。在此语句之后,不再进行路由。

这就是为什么您的RedeliveryPolicyonException其余路线被完全忽略的原因。您配置了2次重新交付尝试,但您编写了5次(ActiveMQ的默认重新交付尝试)。

要解决此问题,请markRollbackOnly移至onException路线的末尾

  1. 如果您从JMS经纪人处消费交易,则消息一定不会丢失

由于在发生错误时将其丢失,因此事务配置存在问题。配置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错误处理程序不会在路由级别上重新交付,而是在处理器级别上重新交付。因此,如果同时配置代理和骆驼重新交付,则可以将它们相乘。