Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does a high Spring JMS DefaultMessageListenerContainer.receiveTimeout parameter mean?

Tags:

spring-jms

I am getting into a project that implemented an IBM MQ listening Spring JMS application and I have troubles understanding the "receiveTimeout" in the DefaultMessageListenerContainer.

Compared to sources from the internet I think my project is kind of special that we are using a really high value of 30 seconds for the "receiveTimeout" parameter and I don't know what this actually means.

I have tried to figure out the meaning of the "receiveTimeout" parameter and I will give you my understanding below after the Spring configuration.

FYI: We are reading/processing many many messages from a queue that are all really small (about 100kb).

This is the spring configuration that we are using:

<bean id="msgListenerContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer"
        p:connectionFactory-ref="mqConnectionFactory" 
        p:messageListener-ref="myMessageListener" p:sessionTransacted="true"
        p:concurrentConsumers="1" p:maxConcurrentConsumers="20"
        p:receiveTimeout="30000" p:idleTaskExecutionLimit="10"
        p:idleConsumerLimit="5" />

If anyone is whondering about the different parameters here is what I have gathered throughout the internet:

The idleConsumerLimit property is used to specify the the maximum number of consumers that are allowed to be idle at a given time. Increasing this limit causes invokers to be created more aggressively. This can be useful to ramp up the number of consumers faster.

idleTaskExecutionLimit: The limit for the number of allowed idle executions of a receive task. The default is 1 causing idle resources to be closed early once a task does not receive a message. idleTaskExecutionLimit property is set to 10 to allow tasks to execute 10 times instead of the default value of 1.

receiveTimeout property is set to 30 seconds to tell the DMLC's receive operation to poll for message for 30 seconds instead of the default one second.

And here is my understanding:

So this means: If there is a heavy load Spring JMS will start up to 20 consumers (maxConcurrentConsumers) and as soon as the load goes down, these consumers will continue to read messages for 30 seconds (receiveTimeout) before closing or going idle. So after that 5 consumers (idleConsumerLimit) will still idle for 10 seconds (?) (idleTaskExecutionLimit) before closing down.

Please correct me if I am wrong.

One internet page stated that my consumers will only read a message every 30 seconds but I do not think that this is the right interpretation of "receiveTimeout".

One issue that we currently have is that we have many many GET's reading from the MQ but not actually getting a message - Like we can have 60'000 GET's that actually are able to read a message compared to 2'100'000 GET's that happend but did NOT read a message.

I am thankful for any help in understanding the behaviour of Spring JMS better.

like image 761
Invest Avatar asked Aug 03 '16 14:08

Invest


1 Answers

The receive timeout is used when asking the broker client if there is more work (receive()) - it's not polling the broker, just polling the client library to see if the broker has sent any more messages. It has nothing to do with how often the messages are received.

When the timeout happens, the container immediately calls receive() again.

A high receive timeout means the container will be less responsive to stop() calls - the container can only stop between receive() calls.

like image 143
Gary Russell Avatar answered Sep 20 '22 23:09

Gary Russell