Apache camel 将消息回滚到死信队列-Apache Camel

Apache camel 将消息回滚到死信队列-Apache Camel,apache-camel,jms,activemq,Apache Camel,Jms,Activemq,我已经设置了ApacheCamel,在其中我使用来自一个队列的消息并对其执行某种操作,然后将其传输到另一个队列 现在,如果出现异常,那么我希望它应该回滚,然后在6次尝试将其发送到死信队列后,当前回滚发生5-6次,但我的消息不会传输到死信队列 发生了什么--> 队列1-->(消耗)--->操作(引发异常)--->回滚-->再次队列1-->(消耗)-->操作(引发异常)--->回滚-->。。。这种情况发生5-6次,然后我的信息就丢失了 我不知道我的消息要去哪里以及它丢失的原因,从我的活动MQ GUI

我已经设置了ApacheCamel,在其中我使用来自一个队列的消息并对其执行某种操作,然后将其传输到另一个队列

现在,如果出现异常,那么我希望它应该回滚,然后在6次尝试将其发送到死信队列后,当前回滚发生5-6次,但我的消息不会传输到死信队列

发生了什么--> 队列1-->(消耗)--->操作(引发异常)--->回滚-->再次队列1-->(消耗)-->操作(引发异常)--->回滚-->。。。这种情况发生5-6次,然后我的信息就丢失了

我不知道我的消息要去哪里以及它丢失的原因,从我的活动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)

我想有很多问题

  • 仅标记回滚
    停止消息
    。在此语句之后,不再执行进一步的路由 这就是为什么您的
    重新交付政策
    以及
    onException
    路线的其余部分被完全忽略的原因。您配置了2次重新交付尝试,但您编写了5次(ActiveMQ的默认重新交付)

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

  • 如果您使用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 redelivery,则它们可以成倍增加

    我认为存在多个问题

  • 仅标记回滚
    停止消息
    。在此语句之后,不再执行进一步的路由 这就是为什么您的
    重新交付政策
    以及
    onException
    路线的其余部分被完全忽略的原因。您配置了2次重新交付尝试,但您编写了5次(ActiveMQ的默认重新交付)

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

  • 如果您使用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 redelivery,则它们可以成倍增加