13

I was reading spring documentation on DefaultMessageListenerContainer

It says "Note: Don't use Spring's CachingConnectionFactory in combination with dynamic scaling. Ideally, don't use it with a message listener container at all, since it is generally preferable to let the listener container itself handle appropriate caching within its lifecycle. Also, stopping and restarting a listener container will only work with an independent, locally cached Connection - not with an externally cached one."

Could anybody explain why?

1 Answer 1

19
  1. You really don't need to cache sessions for listener containers because the sessions are long lived; caching is very beneficial for frequent short use, such as with the JmsTemplate.
  2. The problem is really when cacheConsumers = true (the default). When using dynamic scaling and a listener is stopped, the session is returned to the cache but the broker doesn't know that nobody will actually consume from that session, so you are stuck with messages sitting in the cache that won't be read until that session happens to be reused when the volume increases.

Note: if you wish a JmsTemplate running on the container thread to participate in a container transaction, you should use a CachingConnectionFactory so the producers can be cached, but you should disable caching consumers in the factory if you have variable concurrency.

11
  • Thanks for the response and explanation Gary. Feb 25, 2014 at 9:25
  • Gary just curious if a listener container or a DefaultMessageListenerContainer should not use a SingleConnectionFactory too. Since it is the superclass of the CachingConnectionFactory class. Aug 10, 2014 at 23:47
  • Manual, no, that's ok; the problem is with caching consumers when using variable concurrency in the container; you can end up with a live consumer "stuck" in the cache. Aug 11, 2014 at 12:19
  • Ok understood, I can use SingleConnectionFactory with a DefaultMessageListenerContainer. I have the problem when I have two DefaultMessageListenerContainer with setSubscriptionDurable true, therefore I need set two differents values for setClientId and setDurableSubscriptionName values. If I use SingleConnectionFactory or CachingConnectionFactory always I get "Could not refresh JMS Connection for destination 'topic://branch' - retrying in 5000 ms. Cause: setClientID call not supported on proxy for shared Connection. Set the 'clientId' property on the SingleConnectionFactory instead." Aug 12, 2014 at 15:29
  • 4
    I am not sure how much more elaboration you need. Let's say you have 5 consumers, and the workload drops so the container stops a consumer. If caching is in place, the consumer is left open and put in a cache instead of closing it. Since the broker doesn't know anything about this, he thinks it's still consuming so happily sends up to prefetch messages to it. Since the container is not using that consumer, nobody will see those messages until the workload in the other 4 containers increases such that it decides another consumer is needed and the cached consumer is again used. Nov 13, 2015 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.