簡體   English   中英

未設置ActiveMQ RedeliveryPolicy

[英]ActiveMQ RedeliveryPolicy not being set

我正在使用:

  • SpringBoot 2.0.4
  • ActiveMQ 5.15.5
  • 阿帕奇駱駝2.22.0
  • Java 1.8
  • Groovy的
  • Maven的

基本上,我有一個帶有Apache Camel路由的SpringBoot應用程序,該路由使用ActiveMQ的消息進行事務處理。 我需要在ActiveMQ上設置RedeliveryPolicy,因此當處理中發生錯誤時,將重試該消息多次。

我使用ActiveMQ的bean創建了一個配置類,事務按預期工作,但是RedeliveryPolicy無法工作。 有人可以幫我了解這是怎么回事嗎?

這是產生錯誤的消息的日志輸出:

2018-10-23 10:35:28.005調試10524 --- [mer [entryQueue]] oacsspi.TransactionErrorHandler:為(MessageId:ID:EPIC-LAP-25-50304-1540306817804-)重新傳輸(false)事務開始(0x35d60381) ExchangeId上的4:3:1:1:2:ID-EPIC-LAP-25-1540312510586-0-1))2018-10-23 10:35:28.020 DEBUG 10524 --- [mer [entryQueue]] o。 apache.camel.processor.SendProcessor:>>>>直接://中間交易平台[ID-EPIC-LAP-25-1540312510586-0-1] 2018-10-23 10:35:28.375 DEBUG 10524 --- [mer [entryQueue] oacamel.processor.DefaultErrorHandler:在(ExchangeId:ID-EPIC-LAP-25-1540312510586-(MessageId:ID:EPIC-LAP-25-50304-1540306817804-4:3:1:1:2)上傳遞失敗0-1)。 交付嘗試:0捕獲:java.lang.RuntimeException:ExceptionTest:訂單失敗2018-10-23 10:35:28.390錯誤10524 --- [mer [entryQueue]] oacamel.processor.DefaultErrorHandler:(MessageId:在ExchangeId上ID:EPIC-LAP-25-50304-1540306817804-4:3:1:1:2:ID-EPIC-LAP-25-1540312510586-0-1)。 嘗試交付后已用盡:1個被捕獲:java.lang.RuntimeException:ExceptionTest:訂單失敗

這是我的ActiveMQ配置類:

import org.apache.activemq.ActiveMQConnectionFactory
import org.apache.activemq.RedeliveryPolicy
import org.apache.activemq.camel.component.ActiveMQComponent
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.jms.connection.JmsTransactionManager

import javax.jms.DeliveryMode

@Configuration
class ActiveMQConfiguration {

    @Bean
    ActiveMQConnectionFactory activeMQConnectionFactory() {
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory()
        activeMQConnectionFactory.brokerURL = 'tcp://localhost:61616'
        activeMQConnectionFactory.userName = 'admin'
        activeMQConnectionFactory.password = 'admin'

        RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy()
        redeliveryPolicy.maximumRedeliveries = 3
        redeliveryPolicy.redeliveryDelay = 150L
        redeliveryPolicy.useExponentialBackOff = true
        redeliveryPolicy.backOffMultiplier = 1.5

        activeMQConnectionFactory.setRedeliveryPolicy(redeliveryPolicy)

        activeMQConnectionFactory
    }

    @Bean
    ActiveMQComponent activeMQComponent(@Qualifier('activeMQConnectionFactory')ActiveMQConnectionFactory activeMQConnectionFactory) {
        ActiveMQComponent activeMQComponent = new ActiveMQComponent()
        activeMQComponent.connectionFactory = activeMQConnectionFactory
        activeMQComponent.transacted = true
        activeMQComponent.transactionManager = txManager()
        activeMQComponent.cacheLevelName = 'CACHE_CONSUMER'
        activeMQComponent.lazyCreateTransactionManager = false
        activeMQComponent.deliveryMode = DeliveryMode.PERSISTENT

        activeMQComponent
    }

    @Bean
    JmsTransactionManager txManager(@Qualifier('activeMQConnectionFactory') ActiveMQConnectionFactory activeMQConnectionFactory) {
        JmsTransactionManager txManager = new JmsTransactionManager()
        txManager.connectionFactory = activeMQConnectionFactory
        txManager.rollbackOnCommitFailure = true

        txManager
    }

}

不久前,我遇到了dlq隊列的問題-並非代碼中設置的所有參數都能正常工作。 我必須將設置添加到acitvemq配置。 是的,划分配置不是一個好的決定,但我沒有找到其他配置。 以下是我的jms配置類和通過activemq.xml進行示例隊列配置:

@Configuration
@EnableJms
public class JmsConfig {

    private Environment env;

    @Autowired
    public void setEnv(Environment env) {
        this.env = env;
    }

    @Bean(name = "activemq")
    public ActiveMQComponent activemq(@Qualifier("activemqTransactionManager") JmsTransactionManager jmsTransactionManager,
                                      @Qualifier("activemqConnectionFactory") ConnectionFactory connectionFactory) {
        ActiveMQComponent activeMQComponent = new ActiveMQComponent();
        activeMQComponent.setTransactionManager(jmsTransactionManager);
        activeMQComponent.setConnectionFactory(connectionFactory);
        return activeMQComponent;
    }

    @Bean(name = "activemqJmsTemplate")
    public JmsTemplate jmsTemplate(@Qualifier("activemqConnectionFactory") ConnectionFactory connectionFactory) {
        JmsTemplate template = new JmsTemplate();
        template.setConnectionFactory(connectionFactory);
        return template;
    }

    @Bean(name = "activemqTransactionPolicy")
    public SpringTransactionPolicy activemqTransactionPolicy(
            @Qualifier("activemqTransactionManager") JmsTransactionManager jmsTransactionManager) {
        SpringTransactionPolicy springTransactionPolicy = new SpringTransactionPolicy(jmsTransactionManager);
        springTransactionPolicy.setPropagationBehaviorName("PROPAGATION_REQUIRED");
        return springTransactionPolicy;
    }

    @Bean(name = "activemqTransactionManager")
    public JmsTransactionManager activemqTransactionManager(
            @Qualifier("activemqConnectionFactory") ConnectionFactory connectionFactory) {
        return new JmsTransactionManager(connectionFactory);
    }

    @Bean(name = "activemqConnectionFactory")
    public ConnectionFactory connectionFactory(@Qualifier("activemqRedeliveryPolicy") RedeliveryPolicy redeliveryPolicy) {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL("tcp://" + env.getProperty("queue.url"));
        connectionFactory.setTrustAllPackages(true);

        RedeliveryPolicyMap map = connectionFactory.getRedeliveryPolicyMap();
        map.put(new ActiveMQQueue("queueName.DLQ"), redeliveryPolicy);
        return connectionFactory;
    }

    @Bean(name = "activemqRedeliveryPolicy")
    public RedeliveryPolicy redeliveryPolicy() {
        RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
        redeliveryPolicy.setMaximumRedeliveries(0);
        return redeliveryPolicy;
    }
}

activevq.xml中的更改:

<destinationPolicy>
    <policyMap>
        <policyEntries>
            <!--set dead letter queue for our queue. It name will be "myQueueName.DLQ"-->
            <policyEntry queue="myQueueName">
                <deadLetterStrategy>
                    <individualDeadLetterStrategy queuePrefix="" queueSuffix=".DLQ"/>
                </deadLetterStrategy>
            </policyEntry>
            <policyEntry topic=">">
                <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                </pendingMessageLimitStrategy>
            </policyEntry>
        </policyEntries>
    </policyMap>
</destinationPolicy>

<plugins>
<redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
    <redeliveryPolicyMap>
        <redeliveryPolicyMap>
            <redeliveryPolicyEntries>
                <!--Set the redelivery delay to one hour-->
                <redeliveryPolicy queue="myQueueName.DLQ" maximumRedeliveries="-1" redeliveryDelay="3600000"/>
            </redeliveryPolicyEntries>
        </redeliveryPolicyMap>
    </redeliveryPolicyMap>
</redeliveryPlugin>
</plugins>

這里有兩個問題

1.您有兩個交易經理

由於在配置駱駝ActiveMQ組件時需要執行以下兩行,因此需要配置兩個事務管理器。 那是問題的根源。

activeMQComponent.transacted = true // activates local JMS transactions
activeMQComponent.transactionManager = txManager() // additional tx manager

如果您只想使用ActiveMQ的事務性, 則不需要配置Spring事務管理器

配置的這兩行足以與ActiveMQ代理進行本地事務。

activeMQComponent.transacted = true
activeMQComponent.lazyCreateTransactionManager = false

因此,您應該刪除此行以及整個txManager bean

activeMQComponent.transactionManager = txManager()

如果您當前在駱駝路線中設置了交易標記,則也必須將其刪除。 正如我所寫,即使刪除了所有這些,從ActiveMQ消耗的路由仍會被處理。

2.重新交付不起作用

您尚未發布您的Camel路線,但是根據錯誤輸出,我認為代理未重新交付,因為錯誤是由Camel處理的

發生錯誤時將啟動Camel錯誤處理程序oacamel.processor.DefaultErrorHandler ,並且由於它處理錯誤,因此將消息提交給代理,因此不會進行重新交付。

嘗試禁用駱駝錯誤處理,以查看代理是否重新發送錯誤消息。

errorHandler(noErrorHandler());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM