0

我期待着实现一个有点智能的 MQ 通信模块,它应该能够容忍网络连接中的中断。基本上,如果连接丢失,它应该每 5 秒尝试重新连接一次。

问题如下。我使用以下代码进行阅读:

queueMessage = new MQMessage();
               queueMessage.Format = MQC.MQFMT_STRING;
               queueGetMessageOptions = new MQGetMessageOptions();
               queueGetMessageOptions.Options = MQC.MQGMO_SYNCPOINT + MQC.MQGMO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING;
               queueGetMessageOptions.WaitInterval = 50;
               producerQueue.Get(queueMessage, queueGetMessageOptions);
               msg = queueMessage.ReadBytes(queueMessage.MessageLength);

(当然我之前成功连接到队列管理器等。)
我遇到了以下问题:当这个例程运行时,但在.Get没有连接时,代码只是挂起并停留在.Get. 我使用计时器来查看是否有超时(理论上即使没有必要,对吗?)并且在超时时我尝试重新连接。但是当这个超时到期时,我仍然看到队列管理器报告它已连接,而它显然没有(不再存在物理连接)。自从我使用 SYNCPOINT 以来,这个问题就出现了,当我在写入过程中切断连接时,我遇到了同样的情况,或者在这种情况下,我尝试在 queuemanager 上强制断开连接。所以请帮忙,我应该使用什么设置来避免陷入困境GetPut而是有一个MQException抛出或可控的东西?谢谢!

更新:我使用以下代码连接到 QueueManager。

Hashtable props = new Hashtable();
props.Add(MQC.HOST_NAME_PROPERTY, Host);
props.Add(MQC.PORT_PROPERTY, Port);
props.Add(MQC.CHANNEL_PROPERTY, ChannelInfo);
if(User!="") props.Add(MQC.USER_ID_PROPERTY, User);
if(Password!="") props.Add(MQC.PASSWORD_PROPERTY, Password);
props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);

queueManager = new MQQueueManager(QueueManagerName, props);
producerQueue = queueManager.AccessQueue(
ProducerQueueName,
MQC.MQOO_INPUT_AS_Q_DEF                 // open queue for input
+ MQC.MQOO_FAIL_IF_QUIESCING);   // but not if MQM stopping
consumerQueue = queueManager.AccessQueue(
ConsumerQueueName,
MQC.MQOO_OUTPUT + MQC.MQOO_BROWSE + MQC.MQOO_INPUT_AS_Q_DEF                 // open queue for output
+ MQC.MQOO_FAIL_IF_QUIESCING);   // but not if MQM stopping

不用说,通常代码运行良好。读/写,连接/断开连接正常工作,我只需要弄清楚当前的问题。谢谢!

4

1 回答 1

2

您使用的是哪个版本的 MQ?要使自动重新连接正常工作,队列管理器至少需要为 MQ v701,并且 MQ .NET 客户端需要为 MQ v7.1 级别。

假设您使用的是 MQ v7.1 .NET 客户端,您需要在连接创建期间指定重新连接选项。您需要通过添加以下内容来启用重新连接:

props.Add(MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_RECONNECT);

也可以从 mqclient.ini 文件启用/禁用重新连接。

但令人惊讶的是,为什么在没有网络连接的情况下 Get/Put 会挂起。希望您没有连接与您的应用程序在同一台机器上运行的队列管理器。无需设置任何计时器或类似的东西。您可以发出 MQ 调用,如果连接有任何问题,将引发异常。

更新:

我认为您指IsConnected的是类的属性MQQueueManager。文档说明了此属性的值:“如果为 true,则与队列管理器的连接已建立,并且不知道是否已断开。对 IsConnected 的任何调用都不会主动尝试到达队列管理器,因此有可能物理连接可能会中断,但 IsConnected 仍然可以返回 true。IsConnected 状态仅在队列管理器上执行活动(例如,放置消息、获取消息)时更新。如果为 false,则与队列管理器的连接尚未已制造,或已损坏,或已断开连接。”

如您所见,一个True值并不意味着连接仍处于打开状态。我的建议是调用一个方法,Put/Get 并处理任何抛出的异常。

Put/Get/Disconnect 呼叫挂起似乎是一个问题。我的建议是向 IBM 提出 PMR。

于 2013-07-01T14:35:21.473 回答