ActiveMQ:使用队列(具有并发使用者)和主题来更正配置

时间:2012-03-27 00:06:33

标签: java spring jms activemq apache-camel

我们有一个ActiveMQ / Camel配置,以前只使用消息队列和并发消费者。

但是,我们现在正在介绍消息主题,并发现 - 由于并发消费者 - 主题中收到的消息被消耗了多长时间。

此方案的正确配置是什么?

即,我们希望队列中收到的消息有多个并发消费者,但只有一个消费者为主题上收到的消息定义。

以下是当前配置:

<amq:connectionFactory id="amqConnectionFactory"
    useAsyncSend="true" brokerURL="${${ptl.Servername}.jms.cluster.uri}"
    userName="${jms.username}" password="${jms.password}" sendTimeout="1000"
    optimizeAcknowledge="true" disableTimeStampsByDefault="true">
</amq:connectionFactory>

<bean id="cachingConnectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
    <property name="cacheConsumers" value="true"></property>
    <property name="cacheProducers" value="true"></property>
    <property name="reconnectOnException" value="true"></property>
    <property name="sessionCacheSize" value="${jms.sessioncachesize}"></property>
</bean>

<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="cachingConnectionFactory" />
    <property name="transacted" value="false" />
    <property name="concurrentConsumers" value="${jms.concurrentConsumer}" />
    <property name="maxConcurrentConsumers" value="${jms.max.concurrentConsumer}" />
    <property name="preserveMessageQos" value="true" />
    <property name="timeToLive" value="${jms.timeToLive}" />
</bean>

<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsConfig" />
</bean>

2 个答案:

答案 0 :(得分:3)

您可以为任何主题消费者明确地将concurrentConsumers / maxConcurrentConsumers设置为“1”。

from("activemq:topic:myTopic?concurrentConsumers=1&maxConcurrentConsumers=1")...  

或者,将JmsConfiguration concurrent / maxConcurrentConsumers属性设置为“1”,然后根据需要显式启用队列的并发消耗。

from("activemq:queue:myQueue?maxConcurrentConsumers=5")...  

另外,您可以使用Virtual Topics执行主题消息的并发消费而不会出现重复(强烈建议使用传统主题)

答案 1 :(得分:0)

我最终使用的解决方案是创建一个单独的jmsConfig / activeMQ配置块。

总的移民情况如下:

 <!-- This is appropriate for consuming Queues, but not topics.  For topics, use
jmsTopicConfig / activemqTopics -->
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="cachingConnectionFactory" />
    <property name="transacted" value="false" />
    <property name="concurrentConsumers" value="${jms.concurrentConsumer}" />
    <property name="maxConcurrentConsumers" value="${jms.max.concurrentConsumer}" />
    <property name="preserveMessageQos" value="true" />
    <property name="timeToLive" value="${jms.timeToLive}" />
</bean>

<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsConfig" />
</bean>

<!-- This config limits to a single concurrent consumer.  This config is appropriate for
consuming Topics, not Queues. -->
<bean id="jmsTopicConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="cachingConnectionFactory" />
    <property name="transacted" value="false" />
    <property name="concurrentConsumers" value="1" />
    <property name="maxConcurrentConsumers" value="1" />
    <property name="preserveMessageQos" value="true" />
    <property name="timeToLive" value="${jms.timeToLive}" />
</bean>

<bean id="activemqTopics" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsTopicConfig" />
</bean>

然后,在camel管道中,将主题从activemqTopics bean中删除,如下所示:

<camel:route id="myTopicResponder">
    <camel:from uri="activemqTopics:topic:stockQuotes?concurrentConsumers=1" />
    <camel:to uri="bean:stockQuoteResponder?method=saveStockQuote"/>
</camel:route>