I was looking into a problem between two queue managers, and I thought I would use the stats and accounting to see what was going on. These were pretty well useless. This post should be subtitled, “why you need connection pooling in your web server, for all the wrong reasons“.
As I walked along this morning I pictured a man in a big chair stroking a white car saying “For you Mr Bond, you will not know which applications used MQ, and you will not know what they did. For you, your struggle to understand what is going on, is over”.
Which queue were used?
The first problem was that the stats and accounting only display the mapped queue name, not the opened name.
I had two cluster queues QC1 and QC2. I opened them and put a few messages to each queue. These two queues map down to the SYSTEM.CLUSTER.TRANSMIT.QUEUE – or what ever has been configured for the cluster.
In the accounting data, I had “Queue_Name” :SYSTEM.CLUSTER.TRANSMIT.QUEUE opened twice. There was no entry for QC1 nor for QC2.
It works the same way if you have a QALIAS. If you have queue QA pointing to QL. When you open QA, the accounting record is for QL.
This applies to the statistics records as well.
Which transaction was it?
I had the transaction running as an MDB in my web server.
For my application logic in the onMessage method, which processed the passed message and put the reply, I had
,”Appl_Name” :CF3Name – this is the connection pool name used for putting the message
,”Process_Id” :9987
,”Thread_Id” :42
,”User_Identifier” :colinpaice
“Queue_Name” :SYSTEM.CLUSTER.TRANSMIT.QUEUE
For the listener side of the application, I had
,”Appl_Name” :weblogic.Server
,”Process_Id” :9987
,”Thread_Id” :43
,”User_Identifier” :colinpaice
“Queue_Name” :JMSQIN
Where JMSQIN is the name of the queue the MDB was listening on.
They are both for the same process id (9987) but they are on different threads.
I could only find out what was running from the name of the input queue.
I could not easily tie the two lots of accounting data together. Fortunately I had a dedicated connection pool for the MDB, so I could find it that way. If I had different MDBs using the same connection pool, I would not be able to tell which MDB did which requests.
In someways this is expected. If the listener is using a connection pool – there could be different MDBs serially using the same thread in the connection pool, so it cannot give the name of the MDB, as the MDB name will change.
So to help you understand what is happening in your MQ applications in a web server, you should use connection pooling so you can identify which application issued the requests. Connect pooling also gives you performance benefits.
What happens if you set the application name? See https://developer.ibm.com/messaging/2019/04/09/setting-a-custom-application-name-in-mq-v9-1-2/ (some of which – Java stuff – was available before V9.1.2)
LikeLike
Morag, Thanks for your question .. This was a tough one to answre.
If you use JNDI to get your connection from an external repository, and so are not using connection pooling you can do it. My context.lookup(CF1) gave me a com.ibm.mq.jms.MQConnectionFactory object.
So with JmsConnectionFactory cf = (JmsConnectionFactory) ctx.lookup(cfname);
I could use cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, “MDB2INIT”);
This came out in the accounting. Great
If I used connection pooling I could not use
JmsConnectionFactory cf = (JmsConnectionFactory) ctx.lookup(cfname);
because it could not cast com.ibm.mq.connector.outbound.ConnectionFactoryImpl to JmsConnectionFactory.
I spent a couple of house trying to configure my resource adapter configuration file (ra.xml), but could not find the magic definitions to make it work.
If I used ConnectionFactory cf = (ConnectionFactory) ctx.lookup(cfname)
it did not support cf.setStringProperty(…)
I still got the application name from the Connection pool definition.
So as expected, if you do a MQCONN for each message you process, you can specify the application name.
If you are using connection pooling, you cannot specify the application name in the program, but can specify it in the connection pool.
LikeLike