Hello,
I am testing a Spring JMS implementation where we use an MQSeries queue. The system will end up being high transaction volume, so I wanted to spin up additional connections to the MQSeries queue.

I happened upon the concurrentConsumers and maxConcurrentConsumers settings to throttle the invokers, but this doesn't appear to result in additional connections being made to the queue.

I also found an article indicating that the pubSubDomain value might need to be set to false to force things into the methods to process properly for a queue.

I am concerned about having only one listener connected to the MQSeries, in the case of a system fault where that connection gets disabled I would like to have the ability to throttle up additional connections to aid in our system being robust. Our system will run on multiple JVMs, so there should be a connection established for each, but I would like to have some scalability within a single JVM as well. I understsand that I can scale the consuming side of the picture, but I am mostly concerned about the listening side of it.

Can someone help me understand how to configure a single JVM to make multiple connections to an MQSeries queue?

I also have a question regarding the concurrentConsumers and maxConcurrentConsumers as well... with the configurations below, I expect to see some "Raised scheduled invoker count:" debugging messages as the system throttles the consumers to meet the load, however I am not. The closest thing that I see in the debugging messages are a few "DEBUG org.springframework.jms.listener.DefaultMessageLis tenerContainer102 Lowered scheduled invoker count: 0" messages.

Is there a better way to detect when the invokers are getting throttled up and down? Can someone explain to me the conditions where I can expect to see invokers throttled up or down?

I would like to understand further what configuration has to be changed in order to create this behavior. I have attached our spring-jms.xml and our applicationContext-spring-jms.xml.

Thank you for any help you can provide!

Josh Dalcher

<!-- BEGIN APPLICATION-CONTEXT-SPRING-JMS.XML -->

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//Spring//DTD Bean//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<!-- Application Context -->
<beans>

<bean id="messageListener"
class="org.springframework.jms.listener.adapter.Me ssageListenerAdapter">
<constructor-arg>
<ref bean="projectQueueService" />
</constructor-arg>
<property name="defaultListenerMethod" value="process" />
<!-- we don't want automatic message context extraction -->
<property name="messageConverter">
<bean class="ourproject.jms.MsgConverter"></bean>
</property>
</bean>

<bean id="taskExecutor"
class="org.springframework.scheduling.commonj.Work ManagerTaskExecutor">
<property name="workManagerName" value="wm/ProjectWM" />
<property name="resourceRef" value="false" />
</bean>

<bean id="projectFactory"
class="org.springframework.jndi.JndiObjectFactoryB ean">
<property name="jndiName">
<value>jms/ProjectQueueFactory</value>
</property>
</bean>

<bean id="projectQueue"
class="org.springframework.jndi.JndiObjectFactoryB ean">
<property name="jndiName">
<value>jms/ProjectQueue</value>
</property>
</bean>

<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMes sageListenerContainer102">
<property name="connectionFactory" ref="projectFactory" />
<property name="destination" ref="projectQueue" />
<property name="messageListener" ref="messageListener" />
<property name="taskExecutor" ref="taskExecutor" />
<property name="transactionManager" ref="transactionManager" />

</bean>

</beans>

<!-- BEGIN SPRING-JMS.XML -->

<!DOCTYPE beans PUBLIC "-//Spring//DTD Bean//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<!-- Application Context -->
<beans>
<bean id="jndiTemplate"
class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">
org.apache.activemq.jndi.ActiveMQInitialContextFac tory
</prop>
<prop key="java.naming.provider.url">
vm://localhost
</prop>
<!-- <prop key="java.naming.factory.url.pkgs">org.jnp.interfa ces:org.jboss.naming</prop>-->
</props>
</property>
</bean>

<!-- JMS Queue Connection Factory -->
<bean id="internalJmsQueueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryB ean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>ConnectionFactory</value>
</property>
</bean>

<bean id="ourService"
class="service.OurServiceImpl">
<constructor-arg index="0" ref="ourDAO" />
</bean>

<bean id="ourQueueTarget"
class="service.OurQueueServiceImpl">
<constructor-arg index="0" ref="ourDAO" />
<constructor-arg index="1" ref="ourService" />
</bean>

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
<property name="sessionFactory" >
<ref bean="sessionFactory" />
</property>
</bean>

<bean id="projectQueueListener"
class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">

<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="ourQueueTarget" />
</property>
<property name="transactionAttributes">
<props>
<prop key="process">PROPAGATION_REQUIRED</prop>

</props>
</property>
</bean>



<bean id="messageListener"
class="org.springframework.jms.listener.adapter.Me ssageListenerAdapter">
<constructor-arg>
<ref bean="ourQueueListener" />
</constructor-arg>
<property name="defaultListenerMethod" value="process" />
<!-- we don't want automatic message context extraction -->
<property name="messageConverter">
<bean class="ourproject.jms.MsgConverter"></bean>
</property>
</bean>

<bean id="jmsFactory"
class="org.apache.activemq.spring.ActiveMQConnecti onFactory">
<property name="brokerURL">
<value>vm://localhost</value>
</property>

</bean>

<bean id="projectQueue"
class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="ProjectQueue" />
</bean>

<bean id="taskExecutor"
class="ourproject.task.FeedTask">
</bean>

<!-- and this is the message listener container... -->
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMes sageListenerContainer102">
<property name="connectionFactory" ref="jmsFactory" />
<property name="concurrentConsumers" value="5" />
<property name="maxConcurrentConsumers" value="10" />
<property name="destination" ref="projectQueue" />
<property name="messageListener" ref="messageListener" />
<property name="taskExecutor" ref="taskExecutor" />
<!-- <property name="pubSubDomain" value="false" /> -->
</bean>

<!-- JMS Destination -->
<bean id="projectMDP"
class="org.springframework.jndi.JndiObjectFactoryB ean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>ProjectQueue</value>
</property>
</bean>

<!-- JMS Queue Template -->
<bean id="jmsMDPDispatchTemplate"
class="org.springframework.jms.core.JmsTemplate102 ">
<property name="connectionFactory">
<ref bean="internalJmsQueueConnectionFactory" />
</property>
<property name="defaultDestination">
<ref bean="projectMDP" />
</property>
<property name="receiveTimeout">
<value>30000</value>
</property>
</bean>


<bean id="MsgSender" class="ourproject.jms.MessageSenderImpl">
<property name="jmsTemplate">
<ref bean="jmsMDPDispatchTemplate" />
</property>
</bean>
</beans>