Connecting IBM MQ queue using F5 virtual ip and C+

2019-02-26 06:10发布

问题:

I am trying to connect to some IBM MQ queues using C++. These queues have been defined under different manager queues in different servers. The idea is to connect to a VIP that will balance the workload pointing to each server.

The problem I have is I am using cmqc.h libraries, and in order to connect I have to make use of MQCONN or MQCONNX, for which I need the queue manager name, something that I cannot know as at the moment of the connection I don´t know which one will be used due to F5 balancer.

The code I am currently using as example is the following:

#include <cmqc.h>
#include <cmqxc.h> 
#include <string.h>
#include <stdio.h>
#include <sstream>
#include <stdlib.h>
int main()
{
    MQHCONN connectionHandle;
    MQHOBJ m_SourceQueue;
    MQLONG completionCode = 0;
    MQLONG reasonCode = 0;

    setenv("MQSERVER","SYSTEM.DEF.SVRCONN/TCP/<SERVER_IP_ADDRESS>(56245)",1);
    MQCONN(<QUEUE_MANAGER_NAME>, &connectionHandle, &completionCode, &reasonCode);


    if(MQCC_OK != completionCode)
    {            
        printf ("%s \n", "Error");
        printf ("%s %d \n", "Completion Code", completionCode);
        printf ("%s %d \n", "Reason Code", reasonCode);
    }
    MQDISC(&connectionHandle, &completionCode, &reasonCode);
}

Does somebody have any idea how to connect to the queue when queue manager name is not available?

回答1:

Based on the code you provide you can use NULL, or blanks, or even a * instead of a queue manager name.

For example:

MQCONN("", &connectionHandle, &completionCode, &reasonCode);

MQCONN(" ", &connectionHandle, &completionCode, &reasonCode);

MQCONN("*", &connectionHandle, &completionCode, &reasonCode);

Any of the above will connect to the queue manager listening on the host and port you specify in the MQSERVER environment variable.


MQCONN is documented in the IBM MQ Knowledge Center page MQCONN - Connect queue manager. Quoting a few things related to the queue manager name from this page:

If the name consists entirely of blanks, the name of the default queue manager is used.

In the case of MQSERVER the default queue manager is the one listening on host and port connected to.

The page also has the following in the context of a CCDT but it works the same for MQSERVER:

If an all-blank name is specified, each client-connection channel with an all-blank queue-manager name is tried until one is successful; in this case there is no check against the actual name of the queue manager.

Prefixing an asterisk to the connection name implies that the application does not depend on connecting to a particular queue manager in the group. Suitable applications are:

  • Applications that put messages but do not get messages.
  • Applications that put request messages and then get the reply messages from a temporary dynamic queue.

Unsuitable applications are ones that need to get messages from a particular queue at a particular queue manager; such applications must not prefix the name with an asterisk.


I would suggest that you instead use CCDT (Client Channel Definition Table) as it provides much more flexibility. MQSERVER can only provide the host, port, and channel name. A CCDT will allow you to configure many more options, for example TLS, security exits, max message length to name a few.