1

当我将队列管理器的单个实例更改为多实例队列管理器时,我无法为多实例队列管理器定义多个主机名。现有主机在 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);
    }
}

队列处理程序:

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 中设置备用主机呢?

4

1 回答 1

0

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


对于QueueHandler使用 XMS 的您,您可以使用以下三个属性替换XMSC.WMQ_HOST_NAME属性XMSC.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

对于SendNewMessage使用 IBM MQ C# 库编写的方法,您可以将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 知识中心页面“ MQQueueManager .NET 类”包含有关属性的更多信息。

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

tools\dotnet\samples\cs\base\SimpleClientAutoReconnectPut\SimpleClientAutoReconnectPut.cs
于 2017-07-07T09:21:39.897 回答