Using JMS connection pooling with WebSphere Application Server and WebSphere MQ, Part 1
Creating connections from IBM® WebSphere® Application Server to a Java™ Message Service (JMS) provider such as WebSphere MQ is costly in terms of both time and processor requirements. To improve performance, WebSphere Application Server maintains a pool of free connections that can be given to applications when they request a connection to the JMS provider. This two-part article series explains how JMS connection pooling works in WebSphere Application Server and WebSphere MQ. Part 1 describes how the free connection pool is used, how the contents of the pool are managed, and how the various properties of the pool work together. Part 2 will describe connection pool error handling, configuring the pool to handle concurrent connection requests, and how WebSphere Application Server manages JMS connections to WebSphere MQ.
WebSphere Application Server maintains a pool of connections to a JMS provider in order to improve performance. When an application creates a JMS connection, the application server determines if a connection already exists in the free connection pool. If so, it is returned to the application. Otherwise, a new connection is created. But how does the free connection pool actually work?
Part 1 of this two-part series looks at how the free connection pool is used, how the contents of the pool are managed, and how the various properties of the pool work together.
JMS connection pools
In general terms, a connection pool is a pool of free connections to a JMS provider. JMS includes the concept of connection factories, which are used to create connections to JMS Providers. WebSphere Application Server has a limit on the number of connections that can be created from a factory, specified by the Connection Factory’s Maximum connections property. The default value for this property is 10, which means there can be up to 10 connections created from a factory at any one time.
Each factory has an associated free connection pool. When the application server starts up, the free connection pools are empty. The maximum number of connections that can exist in the free pool for a factory is also specified by the Maximum connections property. Figure 1 below shows the JMS connection pools on an application server that has three JMS connection factories defined:
Figure 1. JMS connection pools
How the connection pool is used
When an application running inside the application server uses the factory to create a connection (by calling
connectionFactory.createConnection(), for example),
the WebSphere Application Server Connection Manager will try to get a connection from the free pool for this factory and return it to the application.
If there are no free connections in the pool, and the number of connections created from this factory has not reached the limit specified in the Factory's Maximum connections property,
the Connection Manager will create a new connection for the application to use.
What happens if an application attempts to create a connection, but the number of connections created from this factory already is equal to the Factory's Maximum connections property? Good question!
In this situation, the application waits for a connection to become available (to be put back in the free pool). The time the application waits is specified in the Connection Pool's Connection timeout property, which has a default value of 180 seconds (3 minutes). If a connection is put back in the free pool within this 3-minute period, the Connection Manager immediately takes it out of the pool again and passes it to the application. However, if the timeout period elapses, a ConnectionWaitTimeoutException is thrown. Figure 2 shows how JMS connections are retrieved from the free connection pool:
Figure 2. How JMS connections are retrieved from the free connection pool
When an application has finished with the connection and closes it by calling
connection.close(), the connection is actually left open, and is returned to the free pool so that it can be reused
by another application. Therefore you can have connections open between WebSphere Application Server and the JMS provider even if no JMS applications are running on the application server.
How message-driven bean listener ports use the connection pool
Assume you have a message-driven bean (MDB) deployed on a WebSphere Application Server V6.1 Base system that is using WebSphere MQ as the JMS provider. The MDB is deployed against a listener port called MDBListener1, which is using the Connection Factory jms/CF1. This connection factory has the Maximum connections property set to 2, which means that only two connections can be created from this factory at any one time.
When the listener port starts up, it attempts to create a connection to WebSphere MQ using the jms/CF1 connection factory. To do so, it requests a connection from the Connection Manager. Since this is the first time the jms/CF1 connection factory has been used, there are no connections in the jms/CF1 free connection pool, so the Connection Manager creates a new one – c1. This connection will exist for the entire life of the listener port.
Figure 3. MDBListener1 using connection c1 from jms/CF1
What happens if you stop the listener port using the WebSphere Administrative Console? In this situation, the Connection Manager will take the connection and put it back into the free pool. The connection to WebSphere MQ is left open.
Figure 4. MDBListener1 is stopped and the connection c1 that it created from jms/CF1 is returned to the factory’s free pool
If the listener port is restarted, it will once again ask the Connection Manager for a connection to the queue manager. You now have a connection c1 in the free pool, so the Connection Manager will take this connection out of the pool and make it available to the listener port. Now, assume that you have a second MDB deployed into the application server, and it is using a different listener port – MDBListener2:
Figure 5. Two MDB Listeners running, using connections created from the same connection factory
Suppose you then try to start a third listener port (MDBListener3), which is also configured to use the jms/CF1 Connection Factory. The listener port requests a connection from the Connection Manager, which looks in the free pool for jms/CF1 and finds that it is empty. It then checks how many connections have already been created from the jms/CF1 factory. Since the Maximum connections property for jms/CF1 is set to 2, and you have already created two connections from this factory, the Connection Manager will wait for three minutes (default value of the Connection timeout property) for a connection to become available:
Figure 6. MDBListener3 must wait for a connection created from the factory jms/CF1 to be returned to the free pool
Consider what happens if listener port MDBListener1 is stopped. Its connection c1 is put into the free pool for jms/CF1, and the Connection Manager then retrieves this connection and gives it to MDBListener3:
Figure 7. MDBListener3 starts up, using the connection previously used by MDBListener1
If you now try to restart MDBListener1, it will have to wait for one of our other listener ports to be stopped before it can restart. If none of the running listener ports are stopped within three minutes, then MDBListener1 will receive a ConnectionWaitTimeoutException and stop.
How Enterprise JavaBeans use the connection pool
This time, let us suppose that we have a single Enterprise JavaBean (EJB) named EJB1 installed into our application server. The bean implements a method called
sendMessage(), which behaves in the following way:
- Creates a JMS connection to WebSphere MQ from the factory jms/CF1, by calling
- Creates a JMS session from the connection.
- Creates a message producer from the session.
- Sends a message.
- Closes the producer.
- Closes the session.
- Closes the connection by calling
Assume that the free pool for the factory jms/CF1 is empty. When the EJB is invoked for the first time, it attempts to create a connection to WebSphere MQ from the factory jms/CF1. As the free pool for the factory is empty, the Connection Manager creates a new connection and gives it to EJB1:
Figure 8. EJB1’s
sendMessage() method is called. It creates a connection c1 to WebSphere MQ by calling connectionFactory.createConnection()
Just before the method exits, it calls
Connection.close(). Rather than closing c1, the Connection Manager takes the connection and puts it into jms/CF1’s free pool:
sendMessage() calls connection.close() before it exits, which causes c1 to be returned to the free pool for jms/CF1
The next time
sendMessage() is called, the
connectionFactory.createConnection() method returns c1 to the application. Now, assume that you have two instances of our EJB running
at the same time. When both instances are calling
sendMessage(), two connections will be created from the jms/CF1 connection factory:
Figure 10. EJB1 and EJB2 are both calling
sendMessage(), and are using connections created from jms/CF1
Now assume that a third instance of the bean is created. When EJB3 invokes
sendMessage(), the method calls
to create a connection from jms/CF1. However, there are currently two connections created from jms/CF1, which is equal to the value of Maximum connections for this factory.
createConnection() method waits for three minutes (the value of the factory’s Connection timeout property) for a connection to become available:
Figure 11. EJB’s
sendMessage() method must wait for a connection to be returned to jms/CF1’s free connection pool
What happens if EJB1’s
sendMessage() method calls
connection.close() and exits. The connection it was using, c1, is put back into the free connection pool.
The Connection Manager then takes the connection back out of the free pool and gives it to EJB3.
The bean’s call to
connectionFactory.createConnection() will then return, allowing the
sendMessage() method to complete:
Figure 12. EJB1’s
sendMessage() method exits, and the Connection Manager gives c1 to EJB3
Listener ports and EJBs using the same connection pool
The two examples above show how listener ports and EJBs can use the connection pool in isolation. However, you can have both a listener port and an EJB running inside the same application server and creating JMS connections using the same connection factory. What are the implications of this?
The key thing to remember is that the connection factory is shared between the listener port and the EJB. For example, assume that you have MDBListener1 and EJB1 running at the same time, and both are using the jms/CF1 connection factory, which means that the connection limit specified by the factory's Maximum connections property has already been reached. If you try to start either another listener port, or another instance of our EJB, they will have to wait for a connection to be returned to jms/CF1’s free connection pool:
Figure 13. MDBListener2 must wait for either c1 or c2 to be returned to jms/CF1 before it can start
Free connection pool maintenance threads
Associated with each free connection pool is a pool maintenance thread, which monitors the free pool to ensure that the connections in it are still valid:
Figure 14. JMS connection pools with their pool maintenance threads
If the pool maintenance thread decides that a connection in the free pool needs to be discarded, it physically closes the connection to the JMS provider.
How does the pool maintenance thread work?
The behaviour of the pool maintenance thread is determined by the value of four properties of the connection pool:
- Aged timeout: The amount of time a connection will be open
- Minimum connections: The minimum number of connections the Connection Manager will keep in a connection factory’s free pool
- Reap time: How often the pool maintenance thread will run
- Unused timeout: How long a connection will remain in the free pool before it is closed
By default, the pool maintained thread runs every 180 seconds (3 minutes), although this value can be changed by setting the connection pool Reap time property. The maintenance thread looks at each connection in the pool, checks how long it has been in the pool, and how much time has elapsed since it was created and last used. If the connection has not been used for a period longer than the value of the connection pool's Unused timeout property, the maintenance thread checks the number of connections currently in the free pool. If that number is greater than the value of Minimum connections, the Connection Manager closes the connection. If the number of connections equals Minimum connections, the connection will not be closed and will remain in the free pool.
The default value of the Minimum connections property is 1, which means that the Connection Manager will always try to keep at least one connection in the free pool, for performance reasons.
The Unused timeout property has a default value of 1800 seconds (30 minutes). By default, if a connection is put back in the free pool and not used again for at least 30 minutes, it is closed, provided that closing it will leave at least one connection in the free pool. This procedure prevents unused connections from becoming stale. To turn this feature off, set this property to zero.
If a connection is in the free pool, and the elapsed time since its creation is greater than the value of the connection pool's Aged timeout property, then it is closed regardless of how long it has been since it was last used. By default, the Aged timeout property is set to 0, which means that the maintenance thread will never perform this check. Connections that have been around for longer than the Aged timeout property are discarded regardless of how many connections will be left in the free pool -- the Minimum connections property does not come into play here. The diagram below shows how the pool maintenance thread cleans up the contents of the connection pool:
Figure 15. How the pool maintenance thread cleans up the connection pool
Disabling the pool maintenance thread
As you can see, the pool maintenance thread does a lot of work when it "wakes up," particularly if there are a large number of connections in the connection factory’s free pool.
For example, suppose there are three JMS connection factories jms/CF1, jms/CF2 and jms/CF3, with each factory configured with the Maximum connections property set to 10. Every three minutes, three pool maintenance threads wake up and scan the free pools for jms/CF1, jms/CF2, and jms/CF3 respectively. If the free pools have lots of connections, the maintenance threads will have a lot of work to do, which can significantly impact performance.
You can disable the pool maintenance thread for an individual free connection pool by setting its Reap time property to 0. Disabling the maintenance thread means that connections will never be closed because the Unused timeout has elapsed. However, they can still be closed if the Aged timeout has passed. When an application has finished with a connection, the Connection Manager checks to see how long the connection has existed, and if that period is longer than the value of the Aged timeout property, the Connection Manager closes the connection rather than returning it to the free pool.
Transactional implications of Aged timeout
As described above, the Aged timeout property specifies how long a connection to the JMS provider remains open before the Connection Manager closes it. Its default value is 0, which means that the connection will never be closed because it is too old. It is best to leave the property at this value, because enabling Aged timeout can have transactional implications when using JMS inside of EJBs.
In JMS, the unit of a transaction is a JMS session, which is created from a JMS connection. It is the JMS session that is enlisted into transactions, and not the JMS connection. Due to the design of the application server, JMS connections can be closed because the Aged timeout has elapsed, even if JMS sessions created from that connection are involved in a transaction. Closing a JMS connection causes any outstanding transactional work on JMS sessions to be rolled back (as described in the JMS Specification). However, the application server will be unaware that the JMS sessions created from the connection are no longer valid. When it tries to use the session to commit or rollback a transaction, an IllegalStateException will occur.
If you wish to use Aged timeout with JMS connections from within EJBs, ensure that any JMS work is explicitly committed on the JMS session before the EJB method that performs the JMS operations exits.
Pool maintenance thread
To understand how the pool maintenance thread works, return to the EJB example (you could also use MDBs and listener ports, as all you really need is a way to get connections in the free pool).
If you recall, EJB1 implements a method called
sendMessage(), which works like this:
- Creates a JMS connection from the factory jms/CF1
- Creates a JMS session from the connection
- Creates a message producer from the session
- Sends a message
- Closes the producer
- Closes the session
- Closes the connection
The connection factory is configured with the Reap time at its default value of 180 seconds (3 minutes), Aged timeout at its default value of 0 seconds, and Unused timeout set to 300 seconds (5 minutes). After the
application server starts up, the
sendMessage() method is invoked. It creates a connection using the jms/CF1 factory, uses it to send a message,
and then calls
connection.close(), which causes c1 to be put into the free pool:
Figure 16. Time=0 seconds.
sendMessage() exits, and c1 is put into the free pool.
After 3 minutes, the pool maintenance thread starts up, and looks at the jms/QCF1 free connection pool. There is a free connection c1 in the pool, so the maintenance thread looks at the time the connection was put back, and compares this to the current time. Three minutes have passed since the connection was put in the free pool, which is less than the value of the Unused timeout property for jms/CF1. Therefore the maintenance thread leaves the connection alone.
Three minutes later, the pool maintenance thread runs again. It finds the connection c1 and determines that it has been in the pool for 360 seconds (6 minutes), which is longer than Unused timeout, so the Connection Manager closes it:
Figure 17. Time=6 minutes. The pool maintenance thread runs and closes c1, because the Unused timeout for the connection has elapsed.
Suppose you now run
sendMessage() again. When the application calls
the Connection Manager creates a new connection to WebSphere MQ because the free connection pool for the connection factory is empty.
This example has shown how the maintenance thread uses the Reap time and Unused timeout properties to prevent stale connections. You may be asking, "How does the Aged timeout property work?". Assume that the Aged timeout property has been set to 300 seconds (5 minutes) and Unused timeout has been set to 0:
Figure 18. Time=0 seconds.
sendMessage() exits, and c1 is put into the free pool.
sendMessage() method is invoked and tries to create a connection from the jms/CF1 connection factory. As the free pool for this factory is empty, the Connection Manager creates a new connection,
c1, and returns it to the application. When
connection.close(), c1 is put back into the free connection pool.
Three minutes later, the pool maintenance thread runs. It finds c1 in the free connection pool, and checks how long ago it was created. The connection has existed for three minutes, which is less than Aged timeout,
so the pool maintenance thread leaves it alone and goes back to sleep. A minute later,
sendMessage() is called again. This time, when it calls
connectionFactory.createConnection(), the Connection Manager discovers that there is a connection c1 available in jms/CF1’s free pool. It takes c1 out of the free pool, and gives it to the application:
Figure 19. Time=4 minutes. c1 is reused by EJB1.
The connection is returned to the free pool when
sendMessage() exits. Two minutes later, the pool maintenance thread wakes up again, scans the contents of jms/CF1’s free pool and discovers c1.
Although the connection was only used 120 seconds ago, the pool maintenance thread closes it because it has been in existence for longer than the value of Aged timeout:
Figure 20. Time=6 minutes. c1 is closed by EJB1, because it has been in existence for longer than Aged timeout (5 minutes).
How the Minimum connections property affects the pool maintenance thread
Using the MDB example again, assume that you have two MDBs deployed in your application server, each using a different listener port. Each listener port is configured to use the jms/CF1 connection factory, which is configured with Unused timeout set to 120 seconds (2 minutes), Reap time set to 180 seconds (3 minutes), and Minimum connections set to 1.
Suppose MDBListener1 is stopped and its connection c1 is put into the free pool. Three minutes later, the pool maintenance thread wakes up, scans the contents of jms/CF1‘s free connection pool, and discovers that c1 has been in the free pool for longer than the value of the factory's Unused timeout property.
However, before closing c1, the pool maintenance thread looks to see how many connections will be left in the pool if this connection is thrown away. Since c1 is the only connection in the free connection pool, the Connection Manager will not close it, because doing so would make the number of connections left in the free pool less than the value of Minimum connections:
Figure 21. c1 is left open, to ensure that the free pool contains at least the Minimum number of connections
Now assume that MDBListener2 is stopped. The free connection pool now contains two free connections – c1 and c2. Three minutes later, the pool maintenance thread runs again. By this time, c1 has been in the free connection pool for 6 minutes, and c2 for 3 minutes.
The pool maintenance thread checks c1 and discovers it been in the pool for longer than the value of Unused timeout. The thread then checks to see how many connections are in the free pool, and compares this to the value of the Minimum connections property. Since the pool contains two connections, and Minimum connections is set to 1, the Connection Manager closes c1.
The maintenance thread now looks at c2. This has also been in the free connection pool for longer than Unused timeout. However, since closing c2 would leave the free connection pool with less than the number Minimum connections in it, the Connection Manager leaves it alone:
Figure 22. Both c1 and c2 have been in the free pool for longer than Unused timeout. However, only c1 is closed, to ensure that the pool contains at least the Minimum number of connections.
This article explained how WebSphere Application Server pools free connections to JMS providers in order to improve performance. It showed you how EJB applications and MDB listener ports use the free pool when creating JMS connections, what happens to these connections when the application and listener port have finished with them, and how the pool maintenance thread cleans up the free connection pool to prevent JMS from becoming stale. The article also explained the behaviour of a number of connection pool properties.
Part 2 describes advanced connection pool properties, how stale connections are purged from the pool, and how WebSphere Application Server JMS connection pooling works when WebSphere MQ is used as the JMS provider.
- Using JMS connection pooling with WebSphere Application Server and WebSphere MQ, Part 2
- Configure WebSphere Application Server to make message-driven beans process messages in a strict order
- How MDB listeners work with a listener port in WebSphere Application Server
- How WebSphere Application Server handles poison messages
- How the maximum sessions property on the listener port affects WebSphere Application Server performance
WebSphere Application Server developer resources page
Technical resources to help you use WebSphere Application Server.
WebSphere Application Server product page
Product descriptions, product news, training information, support information, and more.
WebSphere Application Server information center
A single Eclipse-based Web portal to all WebSphere Application Server documentation, with conceptual, task, and reference information on installing, configuring, and using WebSphere Application Server.
WebSphere Application Server information roadmaps
Roadmap of articles and resources to help you with installation, migration, administration, development, troubleshooting, and understanding the underlying technology.
WebSphere Application Server documentation library
WebSphere Application Server product manuals.
WebSphere Application Server support
A searchable database of support problems and their solutions, plus downloads, fixes, problem tracking, and more.
WebSphere MQ developer resources page
Technical resources to help you design, develop, and deploy messaging middleware with WebSphere MQ to integrate applications, Web services, and transactions on almost any platform.
WebSphere MQ product page
Product descriptions, product news, training information, support information, and more.
WebSphere MQ V6 trial download
A no-charge trial download of WebSphere MQ V6. Includes limited online support for Windows® and Linux® installations at no charge during the trial period.
WebSphere MQ V6 information center
A single Eclipse-based Web portal to all WebSphere MQ V6 documentation, with conceptual, task, and reference information on installing, configuring, and using your WebSphere MQ environment.
WebSphere MQ documentation library
WebSphere MQ product manuals.
WebSphere MQ SupportPacs
Downloadable code, documentation, and performance reports for the WebSphere MQ family of products.
WebSphere MQ public newsgroup
A non-IBM forum where you can get answers to your WebSphere MQ technical questions and share your WebSphere MQ knowledge with other users.
developerWorks WebSphere Business Integration zone
For developers, access to WebSphere Business Integration how-to articles, downloads, tutorials, education, product info, and more.
WebSphere Business Integration products page
For both business and technical users, a handy overview of all WebSphere Business Integration products
Most popular WebSphere trial downloads
No-charge trial downloads for key WebSphere products.
Technical books from IBM Press
Convenient online ordering through Barnes & Noble.