3

As per our configuration, we have WAS version is 8.5.5.1, IBM MQ version 7.5.0.3. We are using 2 channels to connect to WMQ, one with MAXINST set to 250 and one with 500. SHARECNV is set to 10 for both. Now we have an upper limit of making maximum 1600 connections in a queue manager but we end up crossing that limit after 3-4 days of continuous running of WAS Server.

I want to understand how parameters on WAS side affect this count. We are using Queue Connection Factory and Act Spec for making the connections and we have 23 of each of them. Out of these for 22 the settings in Act Spec and QCF are kept default like max server sessions=10, max connection in connection pool=10, max sessions in session pool set to 10. This services have quite low tps of around 15-20 request per minute. All 22 of them use same channel to connect to queue manager with MAXINST set to 250. 1 gets quite high load with peak of 80 requests per second(aprox 40 per server) for which max server sessions=40, max connection in connection pool=40, max sessions in session pool is set to 10.Connection Timeout, Reap Time, Unused Timeout and Aged timeout values are kept default for all.

With these settings we end up making around 1200 connection on the channel used by 22 services and around 500 for the other channel after 2-3 days of continuous running. These build up over a period of time. Now I want to tune these settings so that we don't end up crossing the connection count limit and also don't end up having no connections available. So I have a few questions:

  1. What is a better option from performance point of view- reducing max connections in connection pool or max sessions in sessions pool. What should be the ideal values for the load mentioned earlier.

  2. What should be the ideal value for Unused Timeout for Connection Pool and Session Pool which is set to 30 mins by default. If we reduce it to say 5 mins, what implications could it have on performance of failure to get the connections.

  3. Is there some setting that can be done at WMQ side so that the idle/unused connections are closed or this can happen only from the client side.

  4. DISCINT parameter value is set to zero and HBINT to 300. What should be the ideal value.

I ran below command to view the connections

echo "DIS CONN(*) TYPE(*) CONNAME CHANNEL OBJNAME OBJTYPE" | mqsc -e -m     QM-p width=1000 | grep -o '^\w\+:\|\w\+[(][^)]\+[)]' | awk -F '[()]' -v OFS="," 'function printValues() { if ("CHANNEL" in p) { print p["CHANNEL"], p["CURSHCNV"], p["CONNAME"],p["CHSTADA"],p["CHSTATI"],p["LSTMSGDA"],p["LSTMSGTI"],p["OBJNAME"],p["OBJTYPE"],p["ASTATE"] } } /^\w+:/ { printValues(); delete p; next } { p[$1] = $2 } END { printValues() }' | grep MYCHANNEL

MYCHANNEL,,10.215.161.65,,,,,,,NONE
MYCHANNEL,,10.215.161.65,,,,,,,SUSPENDED
    MYCHANNEL,,10.215.161.65,,,,,MYQUEUE01,QUEUE,ACTIVE

I can see a lot of connection in None and suspended state which do not have any OBJNAME or OBJTYPE associated. I have tried simulating the issue in Test and same thing happens and these connections keeps on increasing as we keep in hitting requests. Can someone tell me why these connections are getting created. Also it looks like these connections will never be used by the application.

This is how connection are made and closed in the application: We have an abstrack bean class which is extended by all MDB's

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
public class TrackBeanV2 extends AbstractServiceBean implements MessageListener {//code}

The abstrack bean handles creation and closing of connections in following manner:

public abstract class AbstractServiceBean {

@Resource(name = "myQCF", type = QueueConnectionFactory.class, shareable = true, description = "Reply Connection Factory")
private ConnectionFactory replyCF; 

@PostConstruct
private void postConstruct() {
        replyConnection = replyCF.createConnection();

    }  catch (JMSException e) {
        throw new RuntimeException("Failed to create JMS Connection");
    }

}
@PreDestroy
private void preDestroy() {
    try {
        replyConnection.close();
    } catch (JMSException e) {
        throw new RuntimeException("Failed to close JMS connection", e);
    }
}

private void sendResponseMessage(String outputMessageText, String jmsMessageID , Destination replyDestination) {
    TextMessage replyMessage = null;
    try {           
        createSession();    
        createProducer();
        replyMessage = createReplyMessage(outputMessageText , jmsMessageID);    
        sendReply(replyMessage, replyDestination);  
        closeProducer();
        closeSession();
    } catch (JMSException exp) {
        handleException(exp);
    }
}
private void createSession() throws JMSException{
    replySession = replyConnection.createSession(true, 0);                  
}`
private void createProducer() throws JMSException{                              
    replyProducer = replySession.createProducer(null);      
}

private void closeSession() throws JMSException {
    if (replySession != null) {
        replySession.close();
    }
}

private void closeProducer() throws JMSException{
    if (replyProducer != null) {            
        replyProducer.close();          
    }
}   
private void sendReply(TextMessage replyMessage, Destination replyDestination) throws JMSException {    
    logMessages(replyMessage.getText(), "RESPONSE MESSAGE");
    replyProducer.send(replyDestination, replyMessage);
}

I have not added other methods of the class which marshalling/unmarshalling and other stuff.

Neel
  • 199
  • 3
  • 18
  • MAXINST are set as 250 and 500 only but with SHARECNV set to 10 we are able to get more connections than 750, we have an upper limit of 2500 for connections of which 1600 are avaialble for SVRCONN channels. – Neel Feb 11 '17 at 18:56
  • @JoshMc Also MAXINSTC is set to 999999999, which i guess is default value. I have checked no of connections used and when they reach the upper limit it is usually 1250 for the channel with 250 instances and 350 for channel with 500 instances. These settings may not have been properly set as the no of services and load have gradually increased for the application but these parameters have not been changed accordingly. That is what I want to do now. – Neel Feb 11 '17 at 19:04
  • Using following command: echo "DIS CONN(*) TYPE(CONN) CONNAME CHANNEL" | mqsc -e -m QM1 -p width=1000 | grep "CHANNEL(A.QM1.CH1)" |wc -l – Neel Feb 11 '17 at 21:08
  • @JoshMc I have updated the question with code used for opening and closing of connections – Neel Feb 17 '17 at 15:12
  • With my limited knowledge of Java and the JMS API it appears you are doing things correctly in closing the producer, the session and in your @PreDestroy the connection itself. Maybe someone else with more JMS knowledge can review and help. If you increase MAXINST to 290, what happens when you reach the upper limit of connections from WAS at around 286. Currently you are hitting the MQ MAXINST level before this happens. – JoshMc Feb 17 '17 at 15:59
  • I actually decreased no of connection in connection pool and session in session pool. No of instances do not cross more than 250 now but issue starts coming as we get closer to 2000 connections.. so issue seems to be with no of connections and not no of instances – Neel Feb 18 '17 at 01:13

3 Answers3

2

After doing lot more analysis and trying out different WAS and MQ settings, we ruled out any issue with configuration and code. While researching found following link http://www-01.ibm.com/support/docview.wss?uid=swg21605479. The issue was with Wily Introscope tool used to monitor the WAS server, it was making connections with MQ and not releasing them. We removed the monitoring from the Server and it is working fine since then. Thanks everyone here for their support.

Neel
  • 199
  • 3
  • 18
1

There is a IBM developerWorks blog post "Avoiding run-away numbers of channels" by @MoragHughson that goes into detail about the various settings on a queue manager to limit total maximum channels for the entire queue manager (MaxChannels in qm.ini), a single channel (MAXINST), and a single client machine connecting to a channel (MAXINSTC).

There is MQGem Software blog post "MaxChannels vs DIS QMSTATUS CONNS" also by @MoragHughson (Thank you Morag for the helpful posts) that goes into detail on the differences between a connections (DIS CONN) and channels (DIS CHS).

Below are a few commands that can help with reconciling things (note I've tested these on Linux, if you are running on another OS and they don't work let me know and I'll try and provide a working example for that OS):

The command below will show you the connection identifier, channel name associated to the connection if any, and the IP address if any, the output is CONN,CHANNEL,CONNAME.

echo "DIS CONN(*) CHANNEL CONNAME"|runmqsc <QMGR> | grep -o '^\w\+:\|\w\+[(][^)]\+[)]' | awk -F '[()]' -v OFS="," 'function printValues() { if ("CONN" in p) { print p["CONN"], p["CHANNEL"], p["CONNAME"] } } /^\w+:/ { printValues(); delete p; next } { p[$1] = $2 } END { printValues() }'

The command below will show you each running channel instance, the number of shared conversations, and the IP address connecting to the channel, the output is CHANNEL,CURSHCNV,CONNAME.

echo "DIS CHS(*) ALL"|runmqsc <QMGR> | grep -o '^\w\+:\|\w\+[(][^)]\+[)]' | awk -F '[()]' -v OFS="," 'function printValues() { if ("CHANNEL" in p) { print p["CHANNEL"], p["CURSHCNV"], p["CONNAME"] } } /^\w+:/ { printValues(); delete p; next } { p[$1] = $2 } END { printValues() }'

Both of the above commands can by adapted to use the mqsc program that you showed you use in your comments.

JoshMc
  • 10,239
  • 2
  • 19
  • 38
  • Thanks for sharing this. Yes it is the the channel instances that are crossing the limit of 250 for one of the channel. But this count builds over a period of 2-3 days so it seems as if instances are not getting closed or new instances are created instead of using existing ones because load is not that high that these many instances will be required at even peak load. I checked tcp keepalive is set to yes in queue manager and unused timeout is set at 30 mins in queue connection factories. So what could be the reason for such a growth in instances. – Neel Feb 12 '17 at 15:18
  • I did ran the commands and could see number of instances to be 115, curshcnv was varying between 1 to 10 for each instance. This 115 reaches 250 at the time of issue. – Neel Feb 12 '17 at 15:20
  • @Neel Based on the default values, if you have 22 different WAS instances connecting to one single SVRCONN channel and they each have a Act Spec and QCF with default values they can use a max of 13 channels per instance for up to a total of 286 channels which is above the 250 MAXINST you have set. I would suspect that the app is not closing the sessions/connections cleanly and they are saying open and building up. How do you close these in the application? – JoshMc Feb 13 '17 at 04:56
  • These 22 services are using Spring JMS's SessionAwareMessageListener which has a onMessage which provides message and session as arguements, so session directly comes to this method and is not created explicity, then we create producer from session object and in the end close the producer. session in not closed in the code. – Neel Feb 13 '17 at 10:52
  • @Override public void onMessage(TextMessage message, Session session) throws JMSException {//code} MessageProducer producer = session.createProducer(null); producer.close(); – Neel Feb 13 '17 at 10:55
  • Also MaxChannels is set to 2000 in qm.ini. this 2000 limit is for connections or instances? – Neel Feb 13 '17 at 15:28
  • Please read the two blog posts I referenced in my answer, this should clear things up. But short answer is MaxChannels applies to channel instances, each channel can contain connections up to the value of SHARECNV for that channel if coming from the same JRE. – JoshMc Feb 13 '17 at 17:17
  • I have edited some more findings in the questions. can you please have a look and provide some inputs. I have already looked at the posts you have mentioned and lot of other posts and tried many configuration changes but nothing seems to work. – Neel Feb 17 '17 at 10:30
1

We had a similar problem where the connection count used to reach its limit once the application was kept active for hours.

Our catch was to call disconnect() of the queue manager post enqueue or dequeue rather than close(). So make sure your finally block looks something like this.

finally 
{
    queue.close();
    qMgr.disconnect();     //rather than qMgr.close();      
}
dnaik
  • 1,455
  • 1
  • 10
  • 10