10分钟后IBM MQ客户端断开连接:IBM.XMS.IllegalStateException

时间:2019-07-08 14:34:19

标签: .net ibm-mq

我正在使用IBM的此示例。我刚刚复制并粘贴了代码:

https://github.com/ibm-messaging/mq-dev-patterns/blob/master/dotnet/dotNetGet.cs

  • 我正在连接到MQ Server 9.0.0.5版
  • 我正在使用控制台应用程序.Net Framework 4.6.1
  • 安装在本地计算机上的MQ客户端是9.1.0.1

我可以看到一个非常奇怪的行为。该应用程序正常运行,并且能够获取消息。但是,恰好在10分钟后它将断开连接。总是十分钟。

这是捕获的错误:

IBM.XMS.IllegalStateException: Failed to get a message from destination MY_QUEUE.
IBM MQ classes for XMS attempted to perform an MQGET; however IBM MQ reported an error.
Use the linked exception to determine the cause of this error.
   at IBM.XMS.Client.Impl.XmsMessageConsumerImpl.ReceiveInboundMessage(Int64 timeout)
   at IBM.XMS.Client.Impl.XmsMessageConsumerImpl.Receive(Int64 millis)
   at Mq_Get_Tests.SimpleConsumer.ReceiveMessages() in C:\Users\osotorrio\Projects\Temporal\Mq_Get_Tests\Mq_Get_Tests\SimpleConsumer.cs:line 137
Linked Exception : CompCode: 2, Reason: 2009*

IBM示例是否缺少一些配置设置,以允许客户端在闲置10分钟后重新连接?

1 个答案:

答案 0 :(得分:3)

您描述的症状似乎与APAR IT26614: MQ dotnet (.NET) client channel ends abnormally when the heartbeat (HBINT) is reached相匹配。

The fix is targeted for delivery in the following PTFs:

Version    Maintenance Level
v8.0       8.0.0.13
v9.0 LTS   9.0.0.7
v9.1 CD    9.1.3
v9.1 LTS   9.1.0.3

截至2019年7月8日,仅发布了9.0.0.7,可以从MQC9: IBM MQ V9 Clients下载


为应该如何工作提供一些背景信息:

  1. MQ客户端应用程序连接到队列管理器时,将协商心跳间隔(HBINT),该间隔为秒数。协商的HBINT始终是SVRCONN与客户端应用程序之间协商的最大值。
    注意SVRCONN HBINT的默认值为300
  2. 基于HBINT,通过以下两种方式之一计算超时:
    1. 如果协商的HBINT小于60,则超时为2x HBINT。 (收到的超时是HBINT通过后的HBINT秒)
    2. 如果协商的HBINT大于或等于60,则TIMEOUT为HBINT +60。(接收超时是HBINT通过后60秒)。
  3. 如果在HBINT时间内没有从队列管理器收到正常流量,则客户端应向该队列管理器发送一个心跳信号,并由心跳响应。客户应等待接收超时时间后才能接收心跳。
  4. 队列管理器还可以向客户端发起“心跳”,但是为防止额外的流量,队列管理器在将“心跳”发送给客户端之前比协商的HBINT多等待了五秒钟。

APAR IT26614纠正了以下三个问题:

  1. 在非托管或托管模式下,有文件记录,如果您不使用CCDT,则HBINT将使用SVRCONN通道的值。实际上,如果不使用CCDT,则客户端的HBINT默认为300,因此这是您看到的最低的HBINT

  2. 特定于托管.NET的客户端HBINT不能低于SVRCONN HBINT,连接将在2059年失败。无论是否使用CCDT,此问题都会影响

    • 使用CCDT,您无法将CLNTCONN HBINT的值设置为小于SVRCONN HBINT
    • 如果没有将SVRCONN HBINT设置为301或更高版本,则不会产生CCDT
  3. 特定于Managed .NET,客户端接收超时的计算以毫秒为单位,而不是秒。在这种情况下,根据IBM长期存在该缺陷,但直到8.0.0.10和9.0.0.4中引入APAR IT16167: Managed .NET client application does not send heartbeat request to queue manager时,缺陷才出现(IBM还确认GA 9.1.0.0中存在此缺陷)。 )。以前不是问题的原因是Managed .NET从未启动过心跳,队列管理器总是在HB​​INT + 5秒时发送心跳,.NET客户端会响应。一旦纠正此错误,就会自动计算出接收超时错误。


基于托管XMS.NET客户端版本9.1.0.1,这是我怀疑发生的事情:

  1. 无论SVRCONN HBINT设置了什么,都将HBINT协商为300秒。
  2. 托管XMS.NET客户端在300秒钟内未从队列管理器收到任何消息后,将向该队列管理器发送心跳信号。
  3. 这时,托管XMS.NET客户端将仅等待60毫秒以等待队列管理器的响应。
  4. 如果Managed XMS.NET客户端在60毫秒内未收到响应,它将向应用程序返回2009错误。
  5. 队列管理器错误日志将显示AMQ9209,其中显示“通过TCP / IP从'dnsname(xx.xx.xx.xx)接收数据时发生错误。

您提到仅在10分钟(600秒)时才看到此消息,但是根据网络的延迟,我以300秒的间隔看到了它。如果要连接到同一服务器或同一本地网段上的队列管理器,则可能永远不会看到此问题。如果通过高延迟WAN电路进行连接,则每300秒可能会遇到一次。如果您连接的网段距离接近30ms,您可能会间歇性地看到它。

我建议您尝试使用9.0.0.7托管XMS.NET客户端,看看它是否为您解决了问题,因为在此版本中,它将等待整整60秒钟来等待队列管理器发出的心跳响应。


如果您想将重新连接添加到示例中,以在不使用包含APAR IT26614的MQ版本的情况下掩盖该问题,则可以使用以下设置:

cf.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, XMSC.WMQ_CLIENT_RECONNECT);
cf.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT_DEFAULT);
//Note that XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT_DEFAULT is 1800

请注意,即使您将MQ的版本与APAR IT26614一起使用,上述操作也是一个好习惯,因为它会告诉Managed XMS.NET客户端在XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT秒内自动尝试重新连接到队列管理器,如果连接丢失。重新连接不适用于与队列管理器的初始连接,仅在连接后才适用。