More than one JMS ConnectionFactory - jms

I am new to JMS and currently developing a simple Chat application explained in Oreilly 'Java Message service'. I've configured a TopicConnectionFactory in ActiveMQ that receives chat messages from TopicPublishers and dispatch that to TopicSubscribers.
My question is 'why do we need to create more than one TopicConnectionFactory' in any JMS application? Since Connectionfactory instances are not tied up with a Topic/Queue, why can't we use one instance of ConnectionFactory for creating connections to all the Topics (or Queues) configured in an application?

Technically speaking you are right. You may be able just to use one ConnectionFactory.
However it is a better design to use multiple ConnectionFactories depending on your requirements so the traffic would be spread out evenly and you do not run out of connections.
So if you know about a JMS Client application that may be problematic (the logic does not allow proper connection handling open/close), you may isolate it to use its own connection factory.
Also some connection factories allow a pool of 10 default active connections at the same time (it depends on the implementation/ settings) if you will need more you may use more than one connection factory.

I've configured a TopicConnectionFactory in ActiveMQ that receives chat messages from TopicPublishers and dispatch that to TopicSubscribers.
Very ambiguous statement. TopicConnectionFactory does not receive or send any messages. It is just one of the admin Objects used to create Connection which in turn creates Session which in turn creates your publishers and subscribers which publish and subscribe the messages.
why can't we use one instance of ConnectionFactory for creating connections to all the Topics (or Queues) configured in an application?
You definitely can. There is no one stopping you from doing that.
As per specs
A connection factory object encapsulates a set of connection configuration
parameters that has been defined by an administrator. A client uses it to
create a connection with a JMS provider.
So unless you have different configuration requirements you can use same ConnectionFactory to create multiple Connections. And yes as otc has mentioned above number of connections is one of the configuration parameter.

Related

Using multiple MQ servers in Java Spring Boot

I have a Java Spring Boot application, and I need to send messages over IBM MQ and then listen for a response on a corresponding queue. I have a primary and (possibly multiple) fail-over MQ hosts. The queue names are different on each host (I have no control over this) so I need to have a different connection factory for each host.
I've looked at the mq-jms-spring code, and think I can adapt this to my needs. However, our current code, which works a comma separated list of hosts (and was written by someone else), creates both a connection factory and a transaction manager using that connection factory. It can use multiple hosts, but since the queue names are different for each host the fail-overs, well, fail. I'm assuming I need to create multiple transaction managers if I have multiple connection factories.
My questions are:
Do I need a transaction manager in this case?
If yes, then do I need a 1-1 relationship of connection factory to transaction manager?
If yes, how do I use the multiple transaction managers? I use the connection factory to write to the queue, but how do I notify spring which transaction factory to use? Does Spring automatically know this or is there some way I need to configure this?

Spring JMS messaging with JmsListener - how it scales?

I'm trying to use Spring JMS messaging with #JmsListener in a scalable way, but I'm not seeing it happening. I have a ConnectionFactory bean that returns a factory that connects to an Oracle Advanced Queue through JMS and a database DataSource pool.
The problem starts as every #JmsListener receiver connects again to JMS (and hence to the database pool). My understand is that I can have many #JmsListener methods, one for each service, but in this way it's doing I'm very limited.
The shared connection is turned on, but since each #JmsListener creates a different DefaultMessageListenerContainer, each one have a database connection.
If I also want the services to handle messages concurrently and set container.setConcurrency("3-5"), then it opens 3 * numberOfListeners connections.
If I use container.setCacheLevel(DefaultMessageListenerContainer.CACHE_NONE) then from each second every listener container connects and disconnects from the JMS/database.
I want something that connects one time (or more, if there is concurrent jobs to process) to JMS/database, not to connect count-of-listener times nor to connect-disconnect at each second for every listener.
You can use a SingleConnectionFactory to wrap the vendor factory and all containers will use the same connection.

JMS - One ConnectionFactory per Queue or one ConnectionFactory for all of the queues

I am using WebSphere with ActiveMQ and ActiveMQ's JCA adapter. In our application, there are a lot of queues for different functionalities. So can you tell me, should I create one ConnectionFactory for each queue(functionality) or only one ConnectionFactory for the whole application and shared for the queues ? And the reason.
Thanks in advance.
Really depends what are your requirements. It is not specific to ActiveMQ, but queuing in general. You usually may create separate connection factories when you have:
different host/port for different queues
different security credentials to connect
want to have different connection pools
So for example, if you want to ensure that at least n connections are available for certain queues you can create separate connection factory for that. As with one connection factory, in some extreme cases, when most of your application load is - let say - on functionalityA queues, then you may not have enough connections for your functionalityB queues and that functionality may suffer starving.

Can I tell camel jms endpoint to share jms connections between routes?

I have a app server that runs multiple camel routes that are reading messages from a JMS Queue, each route runs with different selectors.
We have an app server for each group of clients. So at the end there are multiple connections created to the queue. And that seems to be affecting the read and write performance on the queue.
I tried to use a connection pool, (by the way i am using WMQ), the closest I got is to use spring's CachingConnectionFactory (as described in this post how to configure (spring) JMS connection Pool for WMQ).
I was hoping that the number of connections will reduce from each app server, but that did not happen. Even though i set the size to 5 on the CCFactory, i see 10 connections created to the queue. According to the documentation on CCFactory, explicit closing of the connections is required. Is it possible or does it even make sense to close the connection that is used by a camel route that is reading from a queue? Or is there a way to tell camel routes to share the connections? I thought the use of connection pool and factory will do that, but i don't see that from happening.
Can I achieve what I want to achieve?
Thanks in advance.
what you can do is have only one route reading from the queue instead of many, and then use some camel conditional logic to redirect the message to the correct processing route via direct endpoints, see also this example.
This way there would only one consumer for the queue, instead of multiple consumers each running it's own selector.

Websphere JMS with BUS

Hi I am new to the Websphere JMS. It is bit different configuration i.e we need to create BUS first. I also seen that Connection factory has service bus reference and same service reference is given in Queue. I have following understanding till now
We have enterprise BUS to special needs. i.e BUS has control over the messages before MDB.
We can filter,alter the message in the BUS.
What is relation between Connection factory and Queue.I just seen that Connection factory has same reference of BUS.
Why we refer the same BUS name in Connection factory and Queue.
Please correct my understanding and help me in finding answers of above questions.
SIBus is what holds the messaging engine(s) which contains destinations (point-to-point or publish/subscribe) and actually dispatch messages
In the JMS Part you got the Default JMS Provider which provides you JMS resources (Connection factories, Queues, Topics) which allows you to interact with the SIBus
In the SIBus you define a Destination on a messaging engine with some type (point-to-point or publish/subscribe)
A JMS Connection Factory creates connections to the messaging engine so you can send/receive messages, this is why you need to tell it which Bus you want it to create connections to
A JMS Queue referes to a point-to-point Destination in the SIBus.
Now for your questions:
The Bus itself is not intended to modify or filter messages
Filtering can be done by using a message selector in the MDB, when the MDB attach to the destination it will provide the message selector and the messaging engine will filter messages by it.Regarding modification I am not sure
As I stated before,
ConnectionFactory is what creates connections to the messaging engine while the Queue is an abstraction to the SIB Destination. This is why you need to tell each one which Bus it is interacting with.
Why we refer the same BUS name in Connection factory and Queue.
One reason is that the buses configured in the connection factory and the queue are not necessarily the same. That is the case in a topology with buses that are interconnected using SIBus links. In that case, you can connect to a messaging engine in one bus to send messages to a destination in another bus.

Resources