【问题标题】:WCF timeouts are a nightmareWCF 超时是一场噩梦
【发布时间】:2010-06-09 15:37:43
【问题描述】:

我们有一堆 WCF 服务几乎一直在工作,使用各种绑定、端口、最大大小等。关于 WCF 最令人沮丧的是,当它(很少)失败时,我们无能为力找出失败的原因。有时您会收到如下所示的消息:

System.ServiceModel.CommunicationException: 套接字连接被中止。 这可能是由错误引起的 处理您的消息或接收 远程超时 主机或底层网络 资源问题。本地套接字超时 是“01:00:00”。 ---> System.IO.IOException:无法读取 来自传输连接的数据:一个 现有连接被强制 被远程主机关闭。

问题在于它给你的本地套接字超时仅仅是为了方便。它可能是也可能不是问题的原因。但是好的,有时网络会出现问题。没什么大不了的。我们可以重试什么的。但这是一个巨大的问题。除了无法告诉您究竟是哪个超时(如果有的话)导致失败(“您的服务器端接收超时”或其他内容会有所帮助),WCF 似乎有两种类型的超时。

超时类型 #1) 超时,如果增加,将增加操作成功的机会。所以,相关的超时是一个小时,你上传一个巨大的文件需要一个小时二十分钟。它失败。你增加超时,它成功了。我对这种类型的超时没有任何问题。

超时类型 #2) 超时仅定义您必须等待服务实际失败并给您错误的时间,但会修改此超时对成功的机会没有影响。基本上,在服务请求的第一秒发生了一些事情,这把事情搞砸了。它永远不会恢复。 WCF 不会神奇地为您重试网络连接。好吧,有时建立网络连接并不顺利。但是,如果您的超时时间为 2 小时,则您必须等待 2 个小时,并且它没有机会工作,然后它才最终承认它没有工作并给您错误

但是您在这两种情况下看到的错误看起来是一样的。使用超时类型 #2,看起来您仍然会遇到超时。但是,您可以将所有超时时间增加到 4 年,而它所要做的就是使收到错误消息需要 4 年时间。我知道类型 #2 存在,因为我可以执行已知在成功时不到一分钟内完成的操作,并且需要 2 小时才能失败。但是,如果我杀死它并重试,它很快就会成功。 (如果您想知道为什么不到一分钟的操作可能会出现 2 小时的超时,有时我会使用更大的文件运行该操作,并且可能需要一个多小时。)

因此,为了解决类型 #2 的问题,您希望您的超时非常快,以便您立即知道是否存在问题。然后你可以重试。但是无法克服的问题是,因为我不知道哪些超时是失败的原因,所以我不知道哪些超时是Type#1,哪些是Type#2。可能有一个超时(比如说客户端发送超时),在某些情况下类似于 Type #1,在其他情况下类似于 Type #2。我不知道,也没有办法知道。

有谁知道如何追踪 Type #2 超时,以便我可以将它们设置为较低的值,而不必缩短实际(阅读:Type #1)超时并降低成功的机会?

谢谢。

针对 Andrew Anderson 的评论澄清类型 #2 超时:

我认为客户端请求和开始在服务器上执行的代码之间出现了问题。在我们让服务器代码指示部分进度的所有情况下,它永远不会在未完成整个事情的情况下完成某些操作。因此,服务器代码永远不会执行,执行需要多长时间是无关紧要的(除了它会影响我们首先设置的超时值以适应它)。

【问题讨论】:

  • 要求对类型 2 超时进行澄清:什么失败了?服务端代码,还是从客户端请求连接到实际开始在服务端执行您的方法调用之间的东西?
  • 您能否简单地逐步描述那些“类型 2”-mysterions 以及您所指的确切绑定配置?
  • 这个问题在项目管理(作为客户)和开发人员(作为服务)之间是相似的。任何时候超时,项目管理人员都想知道它是类型 1 还是类型 2。但是,开发人员不知道(他们还没有完成),因此无法提供建议。

标签: .net wcf


【解决方案1】:

我总是在我长期运行的 WCF 服务中添加“心跳”消息。然后可以将 Type #1 超时设置为较低的值(心跳调用频率的 2-3 倍),Type #2 超时变得明显。

【讨论】:

  • 你能说得更具体点吗?听起来您要么能够挑出 Type #1 超时(我不是),要么您能够以某种方式拥有在所有超时都设置为较小值时工作的长时间运行的 WCF 服务。你是如何做到这一点的?
  • 实际上,在重新阅读您的问题后,我会说您可能只需要一个回调(因此您最终会得到一个单向请求,该请求会在未来某个时间得到响应通过单向回调)。仍然需要心跳来防止在等待请求时出现空闲超时。
  • 我想你是在假设单向请求成功并且服务器端代码(请求的处理)是罪魁祸首。请参阅我的编辑中对 Andrew 评论的澄清——我认为这不是问题所在。我认为单向请求与完整操作一样可能失败。
  • 如果我理解斯蒂芬正确,他的意思是你的服务器端代码通过回调向客户端发送心跳。假设您将心跳设置为 10 秒。然后您可以定义 35 秒的超时。如果服务器没有开始执行它的代码,那么也不会发送心跳,并且会发生超时。另一方面,如果服务器可以成功启动,则(长时间运行的)进程正在执行,同时发送心跳以防止超时。
【解决方案2】:

要了解哪个特定超时导致超时或其他错误,请配置并使用tracing

【讨论】:

    【解决方案3】:

    我也遇到了同样的问题,它与坏硬件有关,调试起来非常困难,而且使用wireshark(tcp sniffer)数据包没有显示任何特定错误,我们发现了一些tcp-重试,这可能是一种症状,但实际上数据包只是卡在作为电信调制解调器(倍耐力门 2 plus)的调制解调器路由器内部的某个地方,在更换调制解调器/路由器后,问题完全消失了。

    无论如何,我们发现 wsHttpBinding over http,对于您无法控制且您无法确定网站上安装了哪些硬件的 Internet 连接而言,它更可靠。

    希望这对其他人也有帮助:)

    【讨论】:

      【解决方案4】:

      确保您正确处理服务异常。如果没有正确处理异常,您经常会得到无缘无故断开的连接。此外,如果他们这样做了,并且处理得当,您通常可以获得一些更有用的信息:

      https://msdn.microsoft.com/en-us/library/ms733721(v=vs.110).aspx

      另外,使用可以从客户端调用的“心跳”或常规 ping 方法。我发现客户端路由器在 TCP 连接中内置了一个自动超时,用于结束空闲连接。如果没有心跳方法,客户端路由器可能会过早结束不受 WCF 服务设置影响的连接

      【讨论】:

        猜你喜欢
        • 2022-06-29
        • 1970-01-01
        • 2011-07-01
        • 2011-01-18
        • 2018-10-06
        • 1970-01-01
        • 2018-02-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多