代码之家  ›  专栏  ›  技术社区  ›  Greg Smalter

WCF超时是一场噩梦

  •  21
  • Greg Smalter  · 技术社区  · 14 年前

    我们有大量的WCF服务,它们几乎一直工作,使用各种绑定、端口、最大大小等。WCF最令人沮丧的是,当它(很少)发生故障时,我们无能为力地找出失败的原因。有时你会收到这样的信息:

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

    问题是它给您的本地套接字超时仅仅是为了方便起见。这可能是问题的起因,也可能不是。但好吧,有时候网络会有问题。没什么大不了的。我们可以再试一次。但这是个大问题。除了无法准确地告诉您是哪个超时(如果有的话)导致了失败(“超过了服务器端接收超时”,或者一些有帮助的事情),WCF似乎有两种类型的超时。

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

    超时类型2) 一个超时,它只定义了您必须等待服务实际失败并给您一个错误的时间,但是修改这个超时的值不会影响成功的机会。基本上,在服务请求的第一秒发生了一些事情,这会把事情搞砸。它永远不会复原。WCF不会神奇地为您重试网络连接。很好,有时候建立网络连接不太好。但是,如果你的超时时间是2小时,你必须 在它最终承认它不起作用并给您错误之前,请等待2个小时而没有机会工作。 .

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

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

    是否有人知道如何跟踪类型2超时,以便我可以将它们设置为低值,而不必缩短实际(读:类型1)超时并降低成功的机会?

    谢谢您。

    对2类超时的澄清,以回应安德鲁·安德森的评论:

    我相信在客户机请求和开始在服务器上执行的代码之间会出问题。在我们拥有服务器代码的所有情况下,都表示部分进度,如果不完成整个操作,就永远不会完成某些操作。因此,服务器代码永远无法执行,执行所需的时间与此无关(除此之外,它会首先影响我们设置超时值的目的,以适应它)。

    4 回复  |  直到 8 年前
        1
  •  3
  •   Stephen Cleary    14 年前

    我总是在我的长期运行的WCF服务中放置一个“心跳”消息。然后您可以将类型1超时设置为低值(2-3倍心跳呼叫频率),类型2超时变得明显。

        2
  •  0
  •   Jirka Hanika    12 年前

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

        3
  •  0
  •   Michael Denny    12 年前

    我也遇到了同样的问题,它与一个坏的硬件有关,而且很难调试,而且使用wireshark(TCP嗅探器),数据包没有显示任何特定的错误,我们发现了一些TCP重试,这可能是一个症状,但实际上,数据包只是被卡在作为电信调制解调器的调制解调器路由器中的某个地方。(Pirelli gate 2 plus),更换调制解调器/路由器后,问题完全消失。

    不管怎样,我们发现通过HTTP进行的wshttpbinding对于您没有控制权的Internet连接更可靠,并且您不能确定站点上安装了什么硬件。

    希望这也能帮助其他人:)

        4
  •  0
  •   Robert Perry    8 年前

    确保正确处理服务异常。如果异常处理不正确,您通常会得到无原因退出的连接。此外,如果他们做到了,并且处理得当,您通常可以获得一些更有用的信息:

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

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