I have a process that starts with a topic subscriber.
What happens with a topic subscriber in Tibco if the EMS server shuts down?
I guess it will reconnect. But how many times or for how long it will try to reconnect?
The behaviour depends on various settings, set either on the client or server.
If you for example use a Java client you can set the behaviour through the connection factory:
TibjmsConnectionFactory.setReconnAttemptCount(10);
TibjmsConnectionFactory.setReconnAttemptDelay(1000);
TibjmsConnectionFactory.setReconnAttemptTimeout(1000);
You also can configure this behaviors on the server by using JNDI connections. Those can be defined through the factories.conf file.
BusinessWorks 5 does not reconnect by default, but honors all JNDI propagated settings.
It will try to connect indefinitely.
Related
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.
So using JMS and ActiveMQ, I can be sure that my message sent from my Spring Boot application using JmsTemplate will reach it's destination application even if that destination application is down at the time I send the message to ActiveMQ. As when the destination application starts up, it grabs the message from the queue. Great!
However.
What happens if my Spring Boot application tries to send a JMS message to a queue on the ActiveMQ server, but the ActiveMQ server is down at that point or the network is down and I get a connection refused exception?
What is the recommended way to make sure my application keeps trying to re-sends the message to ActiveMQ until it is successful? Is this something I have to develop into my application myself? Are there any nifty Spring tools or annotations which do this for me? Any advice on best practice or how I should be handling this scenario?
You can try Spring-Retry. Has lots of fine grain controls for it:
http://www.baeldung.com/spring-retry
https://github.com/spring-projects/spring-retry
If it is critical that you don't lose this message, you will want to save it to some alternative persistent store (e.g. filesystem, local mq server) along with whatever retry code you come up with. But for those occasional network glitches or a very temporary mq shutdown/restart, Spring-Retry alone should do the trick.
Couple of approaches I can think of
1. You can set up another ActiveMq as fallback. In your code you don't have to do anything, just change your broker url from
activemq.broker.url=tcp://amq01.blah.blah.com:61616
to
activemq.broker.url=failover:(tcp://amq01.blah.blah.com:61616,tcp://amq02.blah.blah.com:61616)?randomize=false
The rest is automatically taken care of. i.e. when one of them is down, the messages are sent to other.
Another approach is to send to a internal queue (like seda, direct) when activemq is down and read from there.
Adding failover to the url is one appropriate way.
And another reasonable way is to making sure activemq always online , as activemq has the master-slave mode(http://activemq.apache.org/masterslave.html) to get high availability.
We are using Websphere Applicaion Server with Spring JMS, Around 25 applications connect to a IBM MQ. Off-late we are seeing lots of stale connection on the MQ channel to which all these applications connect.
By stale connections I mean the connection are not being used for many days and the application keeps creating new connections. We are not able to identify which application creates these connections that are not being used but they all use the same framework code
WAS version = 8.5.5
Spring = 4.1.2
The Spring jms:listener-container has the following configuration
connection-factory = org.springframework.jms.connection.DelegatingConnectionFactory
acknowledge=auto
concurrency=2-10
Any pointers on any configurations that can be done on QueueConnectionFactory (JMS Resource) on WAS or on the spring side would be helpful.
I know I have not given much information, but the problem is that there are no errors / exceptions, the application creates these connections to the MQ channel and all connections gets cleared when the server is restarted
Adding one more question
We use org.springframework.jms.connection.DelegatingConnectionFactory , for replying back, Does it make sense for us to close the session once we have send back the message?
Thanks in Advance
Charlie
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.
When we set up a queue connection factory, a topic connection factory, a queue, a topic in websphere application server throguh the console, what exactly happens?
The server stores the configuration details in an xml and at server startup, it creates the connection factory(ies), topic(s),queue(s) and puts them in a pool?
I ask because the actual queue(s) and topics(s) itself do not reside on the App server, they reside on a separate (remote) websphere MQ server. So why do we need to 'create' the queues in Websphere App server?
The configuration is metadata for connecting to the remote objects. When the server starts (or an app restarts, or configuration is refreshed), the server reads the .xml, then binds Reference objects into JNDI. The actual connection factories aren't created/pooled until the Reference is first looked up.
I don't have enough experience with JMS to answer your second question, but presumably the metadata is required for the queue in order to access it remotely.