How do I configure an Spring message listener (MDP) to have one instance across a cluster

1.4k Views Asked by At

I have a spring message listener configured with

<bean id="processListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  <property name="concurrentConsumers" value="1"/>
  <property name="clientId" value="process-execute"/>
  <property name="connectionFactory" ref="topicConnectionFactory"/>
  <property name="destination" ref="processExecuteQueue"/>
  <property name="messageListener" ref="processExecuteListener"/>
</bean>

This is running on a cluster with 2 nodes. I see that it's creating 1 consumer per node rather than 1 per cluster. They're both configured with the above xml so they have the same clientId. Yet, when 2 notifications are posted to the queue, both of the listeners are running, each gets a notification, and both execute in parallel. This is a problem because the notifications need to be handled sequentially.

I can't seem to find out how to make it have only one message listener per cluster rather than per node.

1

There are 1 best solutions below

0
On

I solved the problem by having the jms queue block the next consumer until the previous returned. This is a feature in the weblogic server I'm using called Unit of Order. The documentation says you just need to enable it on the queue (I used hash). However, I found that I needed to enable it on the connection factory as well and set a default name. Now I see an MDP per node but 1 waits for 2 to complete before processing and vice versa. Not the solution I intended but it's working nontheless. While oracle specific, it's actually slightly better than a single MDP solution.

Note: I did not set the unit of order name in the spring jmstemplate producer as I do not know if that's possible. I have weblogic setting a default name when none is provided by the producer.