Get Active QM Instance from Multi Instance Queue M

2019-07-24 18:38发布

问题:

I have trouble defining multiple hostname for multi-instance queue manager as I am changing a single instance of queue manager to multi-instance queue manager. The existing host is defined in web.config

<QueueConfigurationSection>
    <QueueConfiguration>
        <add name="SomeQueueHandler" queueManager="QM1" host="99.99.99.01" port="12345" requestQueue="A.B.REQUEST" service="FLATFILE" responseQueue="B.A.RESPONSE" internalResponseQueue="B.A.INTERNAL" channel="A.SVC.SVRCONN" binding="SOAP11TcpBinding" endPoint="net.tcp://localhost:808/Bus/SomeServiceBus.svc/SOAP11" />
    </QueueConfiguration>
  </QueueConfigurationSection>

connection is defined in here

public List<QueueHandler> Queues
{
    get
    {
        if (_queues == null)
            _queues = new List<QueueHandler>();
        if (_queues.Count == 0 && _queueConfiguration != null)
        {
            //create queue handlers from configuration provided
            foreach (QueueConfigurationElement element in _queueConfiguration)
            {
                // Using a different connection factory for each queue
                XMSFactoryFactory factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
                IConnectionFactory connectionProperties = factory.CreateConnectionFactory();
                connectionProperties.SetStringProperty(XMSC.WMQ_HOST_NAME, element.Host);
                connectionProperties.SetIntProperty(XMSC.WMQ_PORT, element.Port);
                connectionProperties.SetStringProperty(XMSC.WMQ_CHANNEL, element.Channel); 
                connectionProperties.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
                connectionProperties.SetIntProperty(XMSC.WMQ_BROKER_VERSION, XMSC.WMQ_BROKER_V1);
                connectionProperties.SetBooleanProperty(XMSC.WMQ_USE_CONNECTION_POOLING, true);

                var queue = new QueueHandler(element.Name, connectionProperties);
                _queues.Add(queue);
            }
        }
        return new List<QueueHandler>(_queues);
    }
}

QueueHandler:

public QueueHandler(string handlerName, IConnectionFactory mqConnectionFactory)
{
    _connectionProperties = mqConnectionFactory;
    var queueConfigurationSection = ConfigurationManager.GetSection(QueueConfigurationSection.SectionName) as QueueConfigurationSection;
    if (queueConfigurationSection != null)
    {
        if (queueConfigurationSection.QueueConfigurationCollection.Cast<QueueConfigurationElement>().Any(qc => qc.Name == handlerName))
        {
            var element = queueConfigurationSection.QueueConfigurationCollection.Cast<QueueConfigurationElement>().First(qc => qc.Name == handlerName);

            _name = element.Name;
            _serviceType = element.DestinationService;
            _queueManagerName = element.QueueManager;
            _channel = element.Channel;
            _requestQueueName = element.RequestQueue;
            _responseQueueName = element.ResponseQueue;
            _internalResponseQueueName = element.InternalResponseQueue;
            _port = element.Port;
            _host = element.Host;

            //set up binding configuraion
            EndpointType bindingEnum;
            if (System.Enum.TryParse(element.Binding, out bindingEnum))
            {
                _messageType = bindingEnum;

                switch (bindingEnum)
                {
                    case EndpointType.FlatFileTcpBinding:
                        //message received from the request queue is plain text - by configuration
                        _dvsBinding = EndpointHelper.CreateFlatFileTCPBinding();
                        break;
                    // ...
                    default:
                        //unsupported endpoint configuration
                        throw new Exception("Unsupported binding configuration");
                }
            }

            //create endpoint address
            _endPointAddress = new EndpointAddress(element.EndPoint);
        }
    }
}

and the hostname and port also defines in the same class in a SendNewMessage method...

try
        {
            if (port != 0)
                MQEnvironment.Port = port;
            if (host != ".")
                MQEnvironment.Hostname = host;
            if (channel != ".")
                MQEnvironment.Channel = channel;
            hMgr = new MQQueueManager(manager);
        }

So how do I set the standby host in MQEnvironment.Hostname?

回答1:

There are multiple ways to provide MQ with multiple host names and port numbers to connect to. My suggestions below specify settings similar to how you already specify host and port.


For your QueueHandler which is using XMS you would replace the properties XMSC.WMQ_HOST_NAME and XMSC.WMQ_PORT with the three properties below. The example below assumes you have defined host1, port1, host2, port2 in your web.config:

connectionProperties.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, XMSC.WMQ_CLIENT_RECONNECT_Q_MGR);
connectionProperties.SetStringProperty(XMSC.WMQ_CONNECTION_NAME_LIST, String.Format("{0}({1}),{2}({3})", element.Host1, element.Port1, element.Host2, element.Port2));
connectionProperties.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT_DEFAULT);

Links to the IBM MQ Knowledge center pages for those properties:

  • XMSC_WMQ_CONNECTION_NAME_LIST
  • XMSC_WMQ_CLIENT_RECONNECT_TIMEOUT
  • XMSC_WMQ_CLIENT_RECONNECT_OPTIONS

Under the IBM install directory you can review the following XMS sample program:

tools\dotnet\samples\cs\xms\simple\wmq\SimpleClientAutoReconnect\SimpleClientAutoReconnect.cs

For your SendNewMessage method which is written using the IBM MQ C# libraries you would replace your MQEnvironment settings with a Hashtable of the properties and change the way you call MQQueueManager to pass the Hashtable. This has the added benefit of being thread safe where MQEnvironment is not. The example below assumes you have defined host1, port1, host2, port2 in your web.config:

properties = new Hashtable();
properties.Add(MQC.CONNECTION_NAME_PROPERTY, String.Format("{0}({1}),{2}({3})", host1, port1, host2, port2));
properties.Add(MQC.CHANNEL_PROPERTY, channel);
properties.Add(MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_RECONNECT_Q_MGR);
hMgr = new MQQueueManager(manager, properties);

The IBM MQ Knowldege center page "MQQueueManager .NET class" has more information on the properties.

Under the IBM install directory you can review the following C# sample program:

tools\dotnet\samples\cs\base\SimpleClientAutoReconnectPut\SimpleClientAutoReconnectPut.cs


标签: ibm-mq xms