Configuring your WebSphere Liberty MDB properly

I found the documentation on how to use and monitor an MDB in a WebSphere Liberty web server environment was not very good.  Some of the documentation is wrong, and some is missing.

I’ll document “how I found it worked”,  in another post I’ll document what the Liberty statistics mean, and how they connects to the configuration.

 

The application

The application is a simple Message Driven Bean.  When this is deployed you specify the queue manager, and which queue the listener task should get messages from.

There are many “moving parts” that need to have matching configuration.  I’ll try to show which bits must match up.

The application deployment

  1. The java IVTMDB.java program has
    1. onMessage(Message message){..} This method is given the message to process.
    2. ConnectionFactory cf = (ConnectionFactory)ctx.lookup(“CF3”); Where CF3 is defined below
  2. Within the WMQ_IVT_MDB.jar
    1. META-INF/ejb-jar.xml has
      1. <ejb-name>WMQ_IVT_MDB_EJBNAME</ejb-name>.  This name is used in the Liberty server.xml file.
      2. <ejb-class>ejbs.IVTMDB</ejb-class>. With a ‘.’ in the name.  Within the jar file is ejbs/IVTMDB.class.   This is the java program that gets executed.  If you specify “ejbs/IVTMDB” you get a java exception IllegalName: ejbs/IVTMDB.
      3. <method><ejb-name>WMQ_IVT_MDB</ejb-name> <method-name>onMessage</method-name> This is the method within the java program which gets the message.  The program has public void onMessage(Message message)
    2. META-INF/MANIFEST.MF This is usually generated automatically
    3. ejbs/IVTMDB.class the actual class file to be used.  This is what was described in the <ejb-class> above.
    4. Other files which may add configuration information for specific web servers.
  3. Within the CCP.ear file
    1. The WMQ_IVT_MDB.jar file described above
    2. META-INF/MANIFEST.MF.   This gets created if one does not exist.
  4. The .ear file is copied to ~/wlp/usr/servers/test/dropins/

The server.xml file for the Liberty instance has

<jmsActivationSpec id="CCP/WMQ_IVT_MDB/WMQ_IVT_MDB_EJBNAME">
  <properties.wmqJms
    destinationRef="AAAA"
    transportType="CLIENT"
    channel="SYSTEM.DEF.SVRCONN"
    hostName="127.0.0.1" 
    port="1414"
    clientID="MDBClientID" 
    applicationName="CCPMDB"
    maxPoolDepth="50"
    poolTimeout="5000ms" 
    queueManager="QMA"/>
  <authData id="auth1" user="colinpaice" password="ret1red"/>
</jmsActivationSpec>
<jmsQueue id="AAAA" jndiName="IVTQueue">
  <properties.wmqJms baseQueueName="IVTQueue"/>
</jmsQueue>

<jmsConnectionFactory jndiName="CF3" id="CF3ID">
  <connectionManager maxPoolSize="6" connectionTimeout="7s"/> 
  <properties.wmqJms queueManager="QMA"
      transportType="BINDINGS"
      applicationName="Hello"/>
</jmsConnectionFactory>

 

Where

  • <jmsActivationSpec> defines the application to the web server.  See  here  for the definition of the content of the jmsActivationSpec.
    • id is composed of
      • CCP is the name of the .ear file
      • WMQ_IVT_MDB is the name of the .jar file
      •  WMQ_IVT_MDB_EJBNAME is the name in the <ejb-name> within the ejb-jar.xml file.
    • The destinationRef=”AAAA” connects the jmsActiviationSpec to the queue name IVTQueue, see jmsQueue below.
    • transportType, channel, hostName, port define how the program connects to the queue manager.  The other choice is transportType=”BINDINGS”.
    • clientID I could not see where this is used.
    • applicationName is only used when transportType=CLIENT.  If you use runmqsc to display the connection, it will have this name if a client connection is used.
    • maxPoolDepth this is the number of instances of your program. If you use runmqsc DIS QSTATUS() the number of IPPROCS can be up to the maxPoolDepth+1.
    • poolTimeout  see below.
    • queueManager is used when transportType=”BINDINGS”.
    • <authdata…> is the userid to be used.
  • </jmsActivation> is the end of the definition.
  • <jmsQueue..> defines a queue.
    • id=…  matches the jmsActivationSpec destinationRef= entry above.
    • jndiName the specified value can be used in an application to look up the queue name.
  • </jmsQueue> defines the end of the queue definition
  • <jmsConnectionFactory.. > defines how the program connects to the queue manager
    • jndiName=”CF3″.  The application issued ConnectionFactory cf = (ConnectionFactory)ctx.lookup(“CF3”) which does a jndi lookup of CF3
    • <connectionManager>defines the  connection properties
      • maxPoolSize=”6″  This means that at most 6 of (onMessage) application instances can get a connection.  If there are 10 instances running –  6 can get a connection and run, 4 will have to wait.
      • connectionTimeout=”7s”  This is meant to say the pool can be shrunk if connections are not used, and not used for 7 seconds.   This allows connections to be freed up.

 

 

How do I configure the numbers?

With the definition <jmsActivationSpec … <properties.wmqJms  maxPoolDepth=”50″… then up to 50 threads can have the queue open, and be getting messages.  Each listener which has got a message will pass the message to the onMessage() method of your application.  Typically the application connects to the queue manager and puts a reply back to the originator.

This means that the connection pool used by the application (CF3 in my case) needs at least a maxPoolDepth connections as the number as the listeners jmsActivationSpec.maxPoolDepth.  The application will wait if there are no connections available.   Liberty provides some basic statistics on the number of connections used, and the number of requests that had to wait.

If you have more than one application using the connection pool, then you need to size the pool for all the potential applications.

I could not find any Liberty statistics as to the number of instances with the input queue open, so you will need to issue the runmqsc DIS QSTATUS(..) and display the number of IPPROCS.

You can change the server.xml configuration to change the connection properties (such as making the maxPoolDepth larger).   This causes all existing instances to stop, and restart, which, in a busy system can cause a short blip in your throughtput.

When connections are not used for a period, they can be freed.  See Using JMS connection pooling with WebSphereApplication Server and WebSphere MQ, Part 1

and Part2.

Unused connections move from the connectionPool to an mqjms holding pool.  Periodically this pool is purged.  After running a workload, I could see from the application trace that some MQDISCs were done 3 minutes + afterwards.

Tuning the inbound “connection pool”.

For the jmsActivationSpec there is no connectionPool as such. There is an internal inbound connectionPool for all MDB listeners.  The maxPoolDepth limits how many connections can be used by the listeners. Every 300 seconds a task wakes up and checks all the “inbound” connections.  If it has not been used for the poolTimeOut duration, then the connection is release.

If you specify a poolTimeOut of 1 second, then the connections could be release after 1 to 301 seconds.  This behaviour means that when the task wakes up, you may have many connections released (MQDISC).  You may want to set the poolTimeOut to 300 seconds so some connections are released when the task runs, and the remainder are released the next time the task runs, to spread the load.

If the poolTimeOut is too small you may get a lot of MQCONN, MQDISC activity.  By using a longer value of poolTimeOut you may avoid this behaviour, so the listeners connect at the start of the day, stay connected most of the day, and disconnect at the end of the day.

You can use maxPoolDepth to throttle the work being processed.  If the number is too small, work will be delayed.  If the number is too large, you may get a spike in activity.  If you use DIS QSTATUS(‘queuename’) you will see the number of threads with the queue open for input and the current depth.  Vary the maxPoolDepth till you get the best balance.

One thought on “Configuring your WebSphere Liberty MDB properly

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s