Spring-boot: Support creating a CachingConnectionFactory when auto-configuring a JMS ConnectionFactory

Created on 21 Feb 2018  路  9Comments  路  Source: spring-projects/spring-boot

This similar to #2956 with the only difference that there is support for ActiveMQ (unless I have missed something).

A way to create such connection factory is by using a BeanPostProcessor as suggested in this SO question.

There is another way, but that one is really hacky and sums down to knowing when the bean for ActiveMQConnectionFactory is created and that you don't have PooledConnectionFactory from ActiveMQ

enhancement

Most helpful comment

If we do this for ActiveMQ I think it would also make sense to do it for Artemis as well.

@snicoll: you commented on the SO question asking for the original issue so I'm guessing you think this makes sense. Should it go in the backlog?

All 9 comments

If we do this for ActiveMQ I think it would also make sense to do it for Artemis as well.

@snicoll: you commented on the SO question asking for the original issue so I'm guessing you think this makes sense. Should it go in the backlog?

If we do this for ActiveMQ I think it would also make sense to do it for Artemis as well.

Of course. Thanks for having a look into it.

I've implemented something in b43a132 that doesn't go in the direction of what was requested here initially but would be more consistent with what we already have. ActiveMQ has already a pooling feature that you can enable and that requires activemq-jms-pool and commons-pool2. This feature is actually independent of ActiveMQ (as a broker) and is available with Artemis as well. One solution would therefore be to use the connection pooling offered by ActiveMQ/Artemis.

We can't simply use CachingConnectionFactory blindly as its usage may lead to semantic side effects. Perhaps we can add opt-in support for that?

Another alternative is to deprecated/remove spring.activemq.pool and introduce a spring.jms.cache where we would applyCachingConnectionFactory. Keeping the two features looks a bit weird to me (as you wouldn't wrap a PooledConnectionFactoruy in a CachingConnectionFactory so we'd effectively conflicting configuration namespaces.

We could keep the infrastructure we have at the moment to let users configure a PooledConnectionFactory if they chose to.

To make things simple, this project seems quite active and is a fork of ActiveMQ's PooledConnectionFactory.

So I went with supporting both as both have their specific use cases. The current proposal is as follows:

  • With no extra configuration, the ConnectionFactory is now cached (session, producers and consumers) using Spring Framework's CachingConnectionFactory. It is possible to tune what is cached and the size of the sessions cache via spring.jms.cache.*
  • If pooling is required, it is used instead as before. ActiveMQ and Artemis are now supported and require (as before) an extra dependency
  • It is possible to have a raw ConnectionFactory by setting spring.jms.cache.enabled=false

Note that the behaviour has been changed for non XA use cases only.

Thoughts?

pinging @garyrussell and @mminella (we'd probably keep this issue for the extended support of pooling and reopen #13065 once we've made up our mind on this).

Unfortunately, this is further complicated by the fact that it's (generally) recommended to not use a CCF with a listener container if the container has variable concurrency and the CCF is is configured to cache consumers - you can end up with an "active" consumer (from the broker's perspective) sitting idle in the cache and it will get prefetch messages that will never be processed (until it's checked out of the cache again).

On the other hand, if you are using transactions and you want JmsTemplate operations to participate in the transaction, you must use the CCF in the container as well as the template (but the same caveat about variable concurrency applies, so consumers shouldn't be cached in this case).

CCF (or a pool) is a must for JmsTemplate operations.

Alright, I'll disable the cache for consumers then and make that opt-in. Consumers in DMLC are already cached so that would only affect JmsTemplate#receive.

I've split the two initiatives. Adding native connection pooling for Artemis is going to be handled by #13523

This change broke the build

Was this page helpful?
0 / 5 - 0 ratings