使用spring camel和atomikos的ActiveMQ.Advisory.Consumer.Queue主题泛滥

时间:2013-01-22 18:51:46

标签: activemq apache-camel spring-jms atomikos

想知道是否有人在使用Atomikos + Camel + ActiveMQ的组合时遇到此问题。我正在使用这个组合以交易方式从队列中剥离消息。它似乎运作良好。问题是我现在处于需要在ActiveMQ中打开咨询消息的情况。在我这样做之后,我注意到所有队列都在不断重建连接。这可以通过ActiveMQ.Advisory.Consumer.Queue主题泛滥来证明。在DEBUG日志记录中也很明显,因为它不断创建连接,打开事务,提交事务并关闭连接。在没有任何实际应用程序生成的消息的情所有其他非事务处理队列/主题都没有此问题。我在其他一些帖子中读过连接池和缓存可以缓解这个问题。看来我不应该使用缓存,而且我已经连接池了。我正在使用此配置:

<bean id="txq" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="txJmsConfig" />
</bean>
<bean id="txJmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="atomikosConnectionFactory" />
    <property name="concurrentConsumers" value="1" />
    <property name="transacted" value="true" />
    <property name="maxConcurrentConsumers" value="${consumers.concurrent.max}" />
    <property name="transactionManager" ref="jtaTransactionManager" />
    <property name="cacheLevelName" value="CACHE_NONE" />
</bean>
<bean id="atomikosConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
    init-method="init" destroy-method="close">
    <property name="uniqueResourceName">
        <value>XA-JMS-ATOMIKOS</value>
    </property>
    <property name="localTransactionMode">
        <value>false</value>
    </property>
    <property name="poolSize">
        <value>4</value>
    </property>
    <property name="xaConnectionFactory">
        <ref bean="xaJmsConnectionFactory" />
    </property>
</bean>
<bean id="xaJmsConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
    <property name="brokerURL"
        value="${queue.address}?jms.watchTopicAdvisories=false&amp;jms.prefetchPolicy.all=0" />
</bean>
<bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp"
    init-method="init" destroy-method="shutdownForce">
    <constructor-arg>
        <props>
            <prop key="com.atomikos.icatch.service">
                com.atomikos.icatch.standalone.UserTransactionServiceFactory
            </prop>
            <prop key="com.atomikos.icatch.max_actives">${batch.transactions.concurrent.max}</prop>
        </props>
    </constructor-arg>
</bean>
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
    init-method="init" destroy-method="close" depends-on="userTransactionService">
    <property name="forceShutdown" value="false" />
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
    <property name="transactionTimeout" value="300" />
</bean>
<bean id="jtaTransactionManager"
    class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="atomikosTransactionManager" />
    <property name="userTransaction" ref="atomikosUserTransaction" />
</bean>

它使用我认为实现池化的AtomikosConnectionFactoryBean。也许我错了?我很想知道是否还有其他人和我在一起,以及他们为解决这个问题做了什么。

@PeterSmith建议实施

Petter,谢谢你的建议。我更改了配置以使用XaPooledConnectionFactory。春天对此并不满意。它认为XaPooledConnectionFactory没有实现XAConnectionFactory。

<bean id="atomikosConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
    init-method="init" destroy-method="close" depends-on="xaJmsPooledConnectionFactory">
    <property name="uniqueResourceName">
        <value>XA-JMS-ATOMIKOS</value>
    </property>
    <property name="localTransactionMode">
        <value>false</value>
    </property>
    <property name="maxPoolSize">
        <value>32</value>
    </property>
    <property name="xaConnectionFactory">
        <ref bean="xaJmsPooledConnectionFactory" />
    </property>
</bean>
<bean id="xaJmsPooledConnectionFactory" class="org.apache.activemq.pool.XaPooledConnectionFactory"
     init-method="start" destroy-method="stop" depends-on="xaJmsConnectionFactory">
    <property name="maxConnections" value="2" />
    <property name="connectionFactory" ref="xaJmsConnectionFactory" />
</bean> 
<bean id="xaJmsConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
    <property name="brokerURL"
        value="${queue.address}?jms.watchTopicAdvisories=false&amp;jms.prefetchPolicy.all=0" />
</bean>

java.lang.IllegalStateException:无法将[org.apache.activemq.pool.XaPooledConnectionFactory]类型的值转换为属性“xaConnectionFactory”所需的类型[javax.jms.XAConnectionFactory]:找不到匹配的编辑器或转换策略

文档声明XaPooledConnectionFactory类实现了javax.jms.XAConnectionFactory,所以此时我有点迷失了。这似乎应该有用。

1 个答案:

答案 0 :(得分:1)

我也使用上面的组合看过这个。

似乎Spring DMLC(正在实现camel jms使用者)正在使用consumer.receive()循环来能够在XA事务中登记读取操作。

在DMLC中没有XA缓存,甚至不使用非轮询的SMLC也是可能的。

尝试将activemq CF包装在org.apache.activemq.pool.PooledConnectionFactory中,看看是否有所帮助。