2013-05-23 1 views
1

У меня есть JMS connectionFactory, что использует ряд подключаемых интерфейсов jms-интеграции. Они работают нормально, но только одно сообщение за раз. Я хотел бы заставить их обрабатывать N одновременных сообщений за раз в разных потоках.Как параллельно обрабатывать пружинные интегральные jms-каналы

Код, который у меня есть, выглядит следующим образом.

весна-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> 

Я знаю, что я могу добавить "одновременные-потребителей" и «max-concurrent-consumer» для входящего-шлюза, чтобы заставить шлюз обрабатывать несколько сообщений. Это приведет к тому, что каждая цепочка/шлюз будет обрабатывать потоки независимо друг от друга. Я хотел бы каким-то образом определить общий пул потоков для всех, кто использует JMS-соединение. Это позволит мне указать 5 потоков и распределить их между шлюзами на основе сообщений, которые сервер предоставляет, но сдерживая потребляющий сервер на управляемый объем работы.

Какие изменения необходимы для обработки несколькими потоками? И как ограничить количество потоков?

ответ

1

Inbound Шлюз является расширением Message-Driven Adapter Channel, так что вы можете использовать все свойства 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> 
+0

К сожалению, я должен был немного яснее. Я изменю свой вопрос, чтобы устранить двусмысленность. –

+0

Я уверен, что вы можете назначить 'taskExecutor'' DefaultMessageListenerContainer', это способ разделить один пул потоков между всеми контейнерами. Но я не уверен, что вы можете сделать это через * int-jms * пространство имен. – hoaz

0

Как предложено hoaz, taskExecutor является решением.

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

и

<int:channel id="fooChannel"> 
    <int:dispatcher task-executor="taskExecutor"/> 
</int:channel> 
Смежные вопросы