如何同时处理spring集成jms通道

时间:2013-05-23 15:57:41

标签: spring concurrency

我有一个JMS connectionFactory,许多spring集成jms inbound-gateway使用。它们工作正常,但一次只能传递一条消息。我想让它们在不同的线程中一次处理N个并发消息。

我现在的代码如下。

弹簧-config.xml中

<import resource="commons/jmsConnectionFactory.xml"/>
<import resource="chain/chain1.xml"/>
<import resource="chain/chain2.xml"/>

jmsConnectionFactory.xml

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL">
        <value>failover:(tcp://mqmaster:61616,tcp://mqslave:61616)?jms.prefetchPolicy.all=1&amp;randomize=false</value>
    </property>
</bean>

链都看起来像这样

<int:channel id="fooChannel"/>
<int-jms:inbound-gateway request-channel="fooChannel" request-destination-name="foo" extract-request-payload="true" />
<int:chain input-channel="fooChannel">
  <int-http:outbound-gateway
     url="...."
     http-method="GET" 
     extract-request-payload="true" />
  <int:object-to-string-transformer />
</int:chain>

我知道我可以向入站网关添加“concurrent-consumers”和“max-concurrent-consumers”,以使网关处理多条消息。这会导致每个链/网关处理它的线程独立管理。我想用某种方法为每个使用JMS连接的人定义一个公共线程池。这将允许我指定5个线程,并根据服务器提供的消息在网关之间分配它们,但是将使用服务器限制为可管理的工作量。

使用多个线程进行处理需要进行哪些修改?我如何限制线程数?

2 个答案:

答案 0 :(得分:1)

入站网关消息驱动的渠道适配器的扩展,因此您可以使用DefaultMessageListenerContainer提供的所有属性。其中一个定义了容器使用的并发消费者数量:

<int-jms:inbound-gateway
    request-channel="fooChannel"
    request-destination-name="foo"
    extract-request-payload="true"
    concurrent-consumers="10" />

您可以找到更多信息here

更新:您似乎可以使用inbound-gateway属性在container中指定对容器实施的引用。这就是说你可以在容器和网关之间重用一个任务执行器实例:

<int-jms:inbound-gateway
    request-channel="fooChannel"
    request-destination-name="foo"
    extract-request-payload="true"
    container="fooChannelContainer" />

<bean id="fooChannelContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer" destroy-method="destroy">
    ...
    <property name="taskExecutor" ref="jmsTaskExecutor" />
</bean>

答案 1 :(得分:0)

正如hoaz建议的那样,taskExecutor就是解决方案。

<task:executor id="taskExecutor" pool-size="4"/>

<int:channel id="fooChannel">
  <int:dispatcher task-executor="taskExecutor"/>
</int:channel>