IBM MQ Little Gem #24: Client HeartBeat Negotiation

This is part of a series of small blog posts which will cover some of the smaller, perhaps less likely to be noticed, features of IBM MQ. Read other posts in this series.

Channel Heartbeat.jpgThe HBINT attribute on a channel, whether queue manager to queue manager channel such as a SENDER and RECEIVER, or a client channel, is a negotiated attribute. This means that as an MQ Administrator you don't have to make them match, the two ends of the channel will figure out the best value to use between them.

HBINT is configured as a value in seconds. The default of 300 seconds equates to 5 minutes. You can set it to any positive number up to 999999 seconds, or you can set it to zero to indicate that you don't want any heartbeats.

The negotiation works as follows. If either end of the channel says HBINT(0) then the negotiated value will also be zero. Otherwise, so long as both ends of the channel have a positive number for HBINT, the negotiated value will become the least frequent interval, which means the biggest number from the two ends.

Here are some examples:-

CLNTCONN HBINT SVRCONN HBINT Negotiated HBINT Comment
300 300 300 If both ends are the same it's easy
0 300 0 If one end says zero then it has to be zero
300 0 0
1 300 300 When different and both non-zero, it's the biggest number
300 600 600

Configuring Heartbeats

To configure different values for heartbeats you need to edit the channel definition. For a queue manager channel it is easy to see how to do this. An MQSC command like this would be used on an object in the queue manager.

ALTER CHANNEL(MQGEM.SVRCONN) CHLTYPE(SVRCONN) HBINT(60)

What may not be so easy to see is how to configure the heartbeat interval at the client end. That is what this post hopes to cover.

Client Channel Definition Table (CCDT)

This way of configuring your client channel is the most akin to the way you saw above for configuring the queue manager side channel definition. Rather than being objects on the queue manager though, they are stored as records in the CCDT file accessed by the client. From IBM MQ V8 you can use runmqsc to create/display/edit the records in the CCDT file (or you can use MQSCX which also handles earlier versions). You would use a command very similar to the one above.

ALTER CHANNEL(MQGEM.SVRCONN) CHLTYPE(CLNTCONN) HBINT(60)

The CCDT file can be used by any of the client implementations (C, Java, .NET).

MQSERVER Environment Variable

The simplest way of setting up a client channel that most people have used at one time or another is the MQSERVER environment variable. All you provide are channel name, transport type and connection name.

export MQSERVER='MQGEM.SVRCONN/TCP/192.168.123.123(1701)'

The rest of the attributes for the CLNTCONN channel are set to default values that you cannot change. These default values are those shown in the MQCD_CLIENT_CONN_DEFAULT structure definition, and from there you can see that HeatbeatInterval is set to 300.

So if you needed to make your client heartbeats less frequent, i.e. negotiate a bigger number, you would only need to change the SVRCONN and as the bigger number of the two it would become the negotiated value.

However if you needed more frequent heartbeats, i.e. negotiate a smaller number, you couldn't do that with MQSERVER, as no matter what you configured on the SVRCONN, the 300 seconds on the CLNTCONN would always be the bigger number and would be used. You'd need to move to the CCDT to solve this problem.

Programmatically Setting Channel Attributes

The other way to set client channel attributes is to code them in your application directly. This differs depending on the language/API you are using. In 'C' (and all procedural languages) you'd code your MQCONNX something like this.

MQCNO cno = {MQCNO_DEFAULT};
MQCD  cd  = {MQCD_CLIENT_CONN_DEFAULT};

.. Set various other channel fields ..
cd.HeartbeatInterval = 60;
cno.Version = MQCNO_VERSION_2;
cno.ClientConnPtr = &cd; /* Use this channel */

MQCONNX(QMgrName,
        &cno,
        &hConn,
        &CompCode,
        &Reason);

This gives you the ability to set the heartbeat interval at both ends of the channel, and you are able to arrange to negotiate whatever value you need.

In the C++ OO classes (stabilized), you'd code your connect method something like this.

pChannel = new ImqChannel;
.. Set various other channel fields ..
pChannel -> setHeartBeatInterval(60);

//Use this channel
qmgr.setChannelReference(pChannel); 

//Connect to the queue manager 
if ( !qmgr.connect() ) { 
...

In other OO classes, that is the MQ Classes for Java (stabilized); the .NET Classes, and through JMS or XMS. There is no way to programatically set the heartbeat interval at the client end. In order to ensure that there is some control over what the heartbeat is negotiated to, these interfaces set the client side HeartBeatInterval to 1. This results in the negotiated heartbeat always ending up as whatever the SVRCONN channel had it set to. These interfaces all allow the use of the CCDT of course, so if you need to change the client side HeartBeatInterval you still have the option to do that.

Viewing the Negotiated HeartBeat Interval value

Of course you don't want to be trying to figure out what the negotiated value was. You just want to ask the channel, "OK, what did you decide to use then?" You can do this using the DISPLAY CHSTATUS command. The HBINT attribute is shown on this display as well as the DISPLAY CHANNEL. On DISPLAY CHSTATUS though, it shows the negotiated value

AMQ8417: Display Channel Status details.
   CHANNEL(MQGEM.SVRCONN)                  CHLTYPE(SVRCONN)
   CONNAME(127.0.0.1)                      CURRENT
   HBINT(300)                              STATUS(RUNNING)
   SUBSTATE(RECEIVE)

Hopefully now you understand how to configure the heartbeat value that you want. Clearly, using a CCDT is the way that gives you most control over this feature of MQ client channels.


Morag Hughson is an MQ expert. She spent 18 years in the MQ Devt organisation before taking on her current job writing MQ Technical education courses with MQGem. She also blogs for MQGem. You can connect with her here on IMWUC or on Twitter and LinkedIn.
0 Comments
1 Like
Recent Stories
IBM MQ Little Gem #27: strmqtrc

IBM MQ Little Gem #26: Publish Delivery Options

IBM MQ Little Gem #25: MCAUSER(*)