| ... Consuming messages from a pool of consumers an be problematic due to prefetch. Unconsumed prefetched messages are only released when a consumer is closed, but with a pooled consumer the close is deferred (for reuse) till the consumer pool closes. This leaves prefetched messages unconsumed till the consumer is reused. This feature can be desirable from a performance perspective. However, it can lead to out-of-order message delivery when there is more than one consumer in the pool. For this reason, the org.apache.activemq.pool.PooledConnectionFactory does not pool consumers. The problem is visible with the Spring DMLC when the cache level is set to CACHE_CONSUMER and there are multiple concurrent consumers. One solution to this problem is to use a prefetch of 0 for a pooled consumer, in this way, it Pooling consumers is supported by Springs CachingConnectionFactory (although turned off by default). In case you use the CachingConnectionFactory with multiple consumer threads configured in Springs DefaultMessageListenerContainer (DMLC) then you either want to turn off consumer pooling in the CachingConnectionFactory (its off by default) or you may want to use a prefetch of 0 when pooling consumers. In this way, the consumer will poll for messages on each call to receive(timeout). Another option is to enable the AbortSlowAckConsumerStrategy on the broker to disconnect consumers that have not acknowledged a Message after some configurable time period.Its generally recommended to turn off consumer caching in Springs CachingConnectionFactory and any other frameworks that allow to pool JMS consumers. Note that Springs DefaultMessageListenerContainer (DMLC) and its CACHE_CONSUMER cache level is not affected by this problem! Springs DMLC does not pool consumers in the sense that it does not use an internal pool with multiple consumer instances. Instead it caches the consumer, i.e. it re-uses the same JMS consumer object to receive all messages for the life time of the DMLC instance. So it behaves pretty much like properly hand written JMS code, where you create the JMS connection, session, consumer and then use this consumer instance to receive all your messages. Hence there is no problem with using CACHE_CONSUMER in Springs DMLC, even with multiple consumer threads, unless you are using XA transactions. XA transactions do not work with CACHE_CONSUMER. However local JMS transactions and non-transacted consumers are just fine to use CACHE_CONSUMER in Springs DMLC. Also note that Camel's JMS or ActiveMQ components use Springs DMLC internally. So everything said above about Springs DMLC and CACHE_CONSUMER applies to these two Camel components as well. Ram vs. Performance Trade-off ... |