从tomee传递到spring时,activeMq redeliveryPolicy被忽略

时间:2014-12-13 05:38:41

标签: spring spring-mvc jms activemq tomee

我使用activeMq 5.10在tomee 1.7.1中部署了一个简单的spring应用程序。 我的问题是,我设定的重新交付政策似乎主要被忽略了,主要是延迟交还。

我的jms监听器我立即抛出异常来测试自动重试。

我的activemq.xml是这样的:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://activemq.apache.org/schema/core
    http://activemq.apache.org/schema/core/activemq-core.xsd
">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<!-- 
    The <broker> element is used to configure the ActiveMQ broker. 
-->
<amq:broker xmlns="http://activemq.apache.org/schema/core" useShutdownHook="false" enableStatistics="true" brokerName="bima" useJmx="true" tmpDataDirectory="${catalina.base}/activemq-data/localhost/tmp_storage" populateJMSXUserID="true" useAuthenticatedPrincipalForJMSXUserID="true" schedulerSupport="true">

    <amq:connectionFactory id="jmsRedeliverConnectionFactory" brokerURL="vm://localhost">
      <amq:redeliveryPolicy>
        <amq:redeliveryPolicy maximumRedeliveries="5" initialRedeliveryDelay="1000" redeliveryUseExponentialBackOff ="true" backOffMultiplier="5" />
      </amq:redeliveryPolicy>

    <amq:persistenceAdapter>
        <amq:kahaDB directory="${catalina.base}/activemq-data/kahadb" checkForCorruptJournalFiles="true" checksumJournalFiles="true" journalMaxFileLength="32mb"/>
    </amq:persistenceAdapter>

    <managementContext>
       <managementContext createConnector="false"/>
    </managementContext>
</amq:broker>

我的tomee.xml看起来像这样:

<tomee>
    <Resource id="ActiveMQResourceAdapter" type="ActiveMQResourceAdapter">
        BrokerXmlConfig=broker:(vm://localhost)
        <!-- ServerUrl=vm://localhost -->
    </Resource>

  <!-- see http://tomee.apache.org/containers-and-resources.html -->
  <Resource id="resources/jms/ConnectionFactory" type="javax.jms.ConnectionFactory"> 
       ResourceAdapter = ActiveMQResourceAdapter 
       BrokerURL = vm://localhost
       maximumRedeliveries 3
       redeliveryBackOffMultiplier 2
       redeliveryUseExponentialBackOff true
       initialRedeliveryDelay 5000
       <!-- BrokerUrl = tcp://localhost:61616 -->
    </Resource> 

    <Resource id="resources/jms/XAConnectionFactory" class-name="org.apache.activemq.ActiveMQXAConnectionFactory">
        BrokerURL = vm://localhost

    </Resource>

    <Resource id="resources/jms/PrintQueue" type="javax.jms.Queue"/>


    <Resource id="testxa" class-name="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
        Url jdbc:mysql://localhost:3306/test?autoReconnect=true
        User root
    </Resource>

    <Resource id="movieDatabase" type="DataSource">
        XaDataSource testxa
        DataSourceCreator dbcp
        UserName root
    </Resource>

  <!-- activate next line to be able to deploy applications in apps -->
    <Deployments dir="apps" />
</tomee>

我的aplication上下文中的jms bean看起来像这样:

<bean id="StartQueue" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory">
        <ref local="jmsFactory" />
    </property>
    <property name="defaultDestinationName" value="StartQueue" />
    <property name="deliveryPersistent" value="true"/>
    <property name="explicitQosEnabled" value="true"/>
</bean>
<bean id="starter" class="org.superbiz.mdb.Start"/>
<jms:listener-container container-type="default" connection-factory="jmsFactory" cache="none" acknowledge="auto" transaction-manager="transactionManager"  concurrency="1" >
    <jms:listener destination="StartQueue" ref="starter" />
</jms:listener-container>

一旦我将maximumRedeliveries 3添加到开始工作的tomee xml,但重新发送都没有延迟。所以有些东西忽略了useExponentialBackOff和initialRedeliveryDelay,或者我错过了将它设置在某个地方?

编辑:

所以我配置为使用外部代理activemq 5.10.0和代理配置

    <!-- START SNIPPET: example -->
<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <value>file:${activemq.conf}/credentials.properties</value>
        </property>
    </bean>

    <bean id="logQuery" class="org.fusesource.insight.log.log4j.Log4jLogQuery"
          lazy-init="false" scope="singleton"
          init-method="start" destroy-method="stop">
    </bean>

    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">

        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry topic=">" >
                  <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                  </pendingMessageLimitStrategy>
                </policyEntry>
              </policyEntries>
            </policyMap>
        </destinationPolicy>

        <plugins>
                    <redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
                        <redeliveryPolicyMap>
                            <redeliveryPolicyMap>
                                <defaultEntry>
                                    <redeliveryPolicy  maximumRedeliveries="5" initialRedeliveryDelay="1000" redeliveryDelay="1000" useExponentialBackOff ="true"  backOffMultiplier="5"/>
                                </defaultEntry>
                            </redeliveryPolicyMap>
                        </redeliveryPolicyMap>
                    </redeliveryPlugin>
                </plugins>
        <managementContext>
            <managementContext createConnector="false"/>
        </managementContext>

        <persistenceAdapter>
            <kahaDB directory="${activemq.data}/kahadb" checkForCorruptJournalFiles="true" checksumJournalFiles="true" journalMaxFileLength="32mb"/>
        </persistenceAdapter>

          <systemUsage>
            <systemUsage>
                <memoryUsage>
                    <memoryUsage percentOfJvmHeap="70" />
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>

        <transportConnectors>
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        </transportConnectors>

        <!-- destroy the spring context on shutdown to stop jetty -->
        <shutdownHooks>
            <bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
        </shutdownHooks>

    </broker>
    <import resource="jetty.xml"/>

</beans>
<!-- END SNIPPET: example -->

和tomee xml

    <tomee>

    <Resource id="ActiveMQResourceAdapter" type="ActiveMQResourceAdapter">
        # Do not start the embedded ActiveMQ broker
        BrokerXmlConfig  =
        ServerUrl = tcp://10.81.1.28:61617>
    </Resource>

    <Resource id="resources/jms/ConnectionFactory" type="javax.jms.ConnectionFactory"> 
        ResourceAdapter = ActiveMQResourceAdapter 
       maximumRedeliveries 1
    </Resource> 
    <Resource id="testxa" class-name="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
        Url jdbc:mysql://localhost:3306/test?autoReconnect=true
        User root
    </Resource>

    <Resource id="movieDatabase" type="DataSource">
        XaDataSource testxa
        DataSourceCreator dbcp
        UserName root
    </Resource>

  <!-- activate next line to be able to deploy applications in apps -->
    <Deployments dir="apps" />
</tomee>

当我尝试并且必须使用相同的activemq xml和tomee xml

启动activemq时,这样可以方便地重新传递队列
    <tomee>
    <Resource id="ActiveMQResourceAdapter" type="ActiveMQResourceAdapter">
        BrokerXmlConfig=broker:(vm://localhost)
        BrokerURL = vm://localhost
    </Resource>

  <Resource id="resources/jms/ConnectionFactory" type="javax.jms.ConnectionFactory">
       ResourceAdapter = ActiveMQResourceAdapter
       maximumRedeliveries 1
    </Resource>


    <Resource id="testxa" class-name="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
        Url jdbc:mysql://localhost:3306/test?autoReconnect=true
        User root
    </Resource>

    <Resource id="movieDatabase" type="DataSource">
        XaDataSource testxa
        DataSourceCreator dbcp
        UserName root
    </Resource>

  <!-- activate next line to be able to deploy applications in apps -->
    <Deployments dir="apps" />
</tomee>

配置被忽略,队列没有被重新传送到需要做的其他事情,所以tomee使用了重新传递策略?

4 个答案:

答案 0 :(得分:0)

我认为它是redeliveryUseExponentialBackOff而不是useExponentialBackOff:http://activemq.apache.org/maven/5.10.0/apidocs/org/apache/activemq/ra/ActiveMQManagedConnectionFactory.html

基本上使用setter。

答案 1 :(得分:0)

为什么不在资源适配器BTW上设置它?

答案 2 :(得分:0)

默认情况下,停用调度程序服务,因此这可能不适用于嵌入式代理。

您是否尝试使用外部添加jar来支持代理的xbean xml配置? (http://tomee.apache.org/jms-resources-and-mdb-container.html

答案 3 :(得分:0)

回答这个旧问题,以便也许有人可以从中受益(我遇到了很多类似的问题)。我有一个类似的问题,其中RedeliveryPolicy没有正确应用。通过将maximumRedeliveries设置为-1,可以无限地重试处理该消息,但是忽略了延迟。原来,由于Springs DefaultMessageListenerContainer上的默认cacheLevel字段,重新交付无法正常工作。

将此级别设置为CACHE_CONSUMER解决了该问题!