从多实例队列管理器获取活动QM实例并进行连接

时间:2017-07-07 06:43:28

标签: ibm-mq xms

我在为多实例队列管理器定义多个主机名时遇到问题,因为我正在将单个队列管理器实例更改为多实例队列管理器。 现有主机在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>

连接在这里定义

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);
        }
    }
}

并且主机名和端口也在SendNewMessage方法的同一个类中定义...

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

那么如何在MQEnvironment.Hostname中设置备用主机?

1 个答案:

答案 0 :(得分:0)

有多种方法可以为MQ提供多个要连接的主机名和端口号。我在下面的建议指定了与您已经指定主机和端口的方式类似的设置。

对于使用XMS的QueueHandler,您可以使用以下三个属性替换属性XMSC.WMQ_HOST_NAMEXMSC.WMQ_PORT。以下示例假定您已在web.config中定义了host1,port1,host2,port2:

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);

指向这些属性的IBM MQ知识中心页面的链接:

在IBM安装目录下,您可以查看以下XMS示例程序:

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

对于使用IBM MQ C#库编写的SendNewMessage方法,您可以使用MQEnvironment属性替换Hashtable设置,并更改调用MQQueueManager的方式传递Hashtable。这具有线程安全的额外好处,而MQEnvironment不是。以下示例假定您已在web.config中定义了host1,port1,host2,port2:

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);

IBM MQ Knowldege中心页面&#34; MQQueueManager .NET class&#34;有关房产的更多信息。

在IBM安装目录下,您可以查看以下C#示例程序:

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