100 分钟后 websphere mq 客户端主题静默访问错误

websphere mq client topic silent access error after 100 miutes

我们正在使用 WebSphereMQ 中的主题集成通信。 使用 MQ 版本 8 的 c# 库,dll 来自从 IBM 官方网站下载的 mqc8_8.0.0.3_win64.zip。 我们连接到服务器没有问题,然后我们访问指定的主题,我们将连接设置为持久连接,提供用户 ID。然后我们进入一个无限循环,每 2 分钟询问一次该主题是否有新消息发布。这很好用。如果客户发布消息 - 我们得到它们。如果我们在没有删除订阅的情况下断开连接,我们可以在重新连接后恢复它并且消息在那里。连接方面似乎没问题。

问题是在半空闲时间后(只是请求新消息,但每次收到代码 2033 - 没有新消息)某些东西停止工作。但是没有其他(例如网络)错误代码。我们不断收到代码 2033,但即使将它们放在那里我们也无法再接收消息。 如果我们断开连接(完全关闭客户端应用程序)并重新连接,消息就在那里,并且它在另一段时间里工作正常。

通过网络数据包嗅探器进行的调试显示,在连接并访问主题后将近整整 100 分钟后,我们的客户端停止发送周期 "get" 消息。然而,它确实从此时开始每 5 分钟发送一次心跳消息——这似乎是客户端(图书馆)的自动功能。 但是,客户端日志显示我实际上仍在发送新消息请求,并且每次我不断收到代码 2033 作为响应,即使消息确实存在。 由于这种情况每 100 分钟发生一次,我们认为这是某种超时,但我们无法确定是什么超时。 经过一番搜索后,我在 IBM 的文档中找到了这个:http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.ref.con.doc/q081860_.htm 关于disconnect interval设置为100分钟,但是在联系了其他公司的MQ服务器管理员后,我确信实际上他们将这个值设置为0,所以应该不是这样。另外,根据网络嗅探,看起来客户端正在停止获取消息而不是服务器断开我们的连接。

还有一个更大的谜题。我们尝试了 queuemanager 的软断开连接并重新连接和重新访问主题,但它没有帮助,好像即使有新的 queuemanager 实例也保留了一些静态字段。我们需要完全关闭客户端程序才能接收消息。一直以来,除了代码 2033(没有新消息)之外,我们没有收到任何其他错误消息。

现在来写一些代码。 每次都使用 connection/reconnection:

public void Connect()
{
    MQEnvironment.Hostname = connectionName;//please assume those are correctly filled values
    MQEnvironment.Port = port;
    MQEnvironment.Channel = channelName;
    queueManager = new MQQueueManager(QueueManagerName);
}

接下来进入正题

public MQTopic AccessTopic(string topicName)
    {
        MQTopic topic = null;
        topic = queueManager.AccessTopic(topicName, null, MQC.MQSO_CREATE | MQC.MQSO_FAIL_IF_QUIESCING | MQC.MQSO_MANAGED | MQC.MQSO_DURABLE | MQC.MQSO_RESUME, null, "subNameXYZ");
        return topic;
    }

接下来,我们读正题。所有函数都使用 Try/Catch statemsnts,但我对它们进行了一些清理以使其更易于查看。这是一个循环,每 2 分钟一次。

public string ReadTopic(MQTopic topic)
    {
        string strReturn = "";
        if (topic != null)
        {
            try
            {
                queueMessage = new MQMessage();
                queueMessage.Format = MQC.MQFMT_STRING;
                queueGetMessageOptions = new MQGetMessageOptions();
                topic.Get(queueMessage, queueGetMessageOptions);
                strReturn = queueMessage.ReadString(queueMessage.MessageLength);
                queueMessage.ClearMessage();
            }
            catch (MQException exp)
            {
                //checking if code = 2033 "no new message"
            }
        }
        return strReturn;
    }

此外,每次循环,在访问readtopic之前,我们检查连接是否正常,如果不正常,则重新连接,如下所示:

public void CheckConnection()
{
    if (!queueManager.IsConnected)
    {
        queueManager.Disconnect();
        queueManager.Close();
        Connect();
    }
}

所以,简而言之:问题是什么会导致我们的连接每次几乎恰好 100 分钟后停止接收来自该主题的消息,即使没有错误消息,并且新消息在该主题之后发布那100分钟? 附带问题:为什么软重连不起作用,为了能够访问我们需要完全关闭程序的消息?

MQ 中几乎没有可能导致此行为的场景。例如,浏览光标可能看不到到达的更新的、优先级更高的消息。尽管队列深度非零,但不完整的消息组也可以 return 2033。但是您的描述不支持这两种情况中的任何一种作为原因。

然而这部分似乎表明 MQ 中存在错误 类:

Debuggin via network packet sniffer revealed that after almost exactly 100 minutes after connection and accessing the topic, our client stops sending the period "get" messages. It does however send hearbeat messages every 5 minutes from this point on - this seems to be clients (libraries) automatic feature. However, client side logging reveals that im actually still sending out requests for new messages and each time i keep getting code 2033 as a response, even if messages are actually there.

类 无法可靠地 return 2033,除非他们首先向 QMgr 询问消息。如果您的数据包捕获是完整的(即感兴趣的网络流没有遍历未被捕获的线程或套接字),那么 类 报告的行为与实际执行的行为不匹配。如果您可以在跟踪下可靠地重现它,IBM 应该能够在 PMR 中解决它。

在那之前,您可能不得不实施变通办法,例如定期重启应用程序。您还可以尝试创建对预定义队列的托管订阅并更改应用程序以对其进行轮询。如果问题与主题对象无关,这将在不影响该主题的任何其他订阅者的情况下解决它。