【问题标题】:WCF Tracing. How I can get the exact reason for closing connection?WCF 跟踪。如何获得关闭连接的确切原因?
【发布时间】:2010-12-28 09:13:03
【问题描述】:

在我的 WCF 服务中,尝试传输大数据时,我经常收到错误消息:底层连接已关闭:连接已意外关闭

我想知道是什么特殊原因引发了这个错误,所以我设置了 WCF Tracing 并且可以读取 traces.svclog 文件。

问题是,我可以在这个文件中看到很多关于流程的信息,我可以看到出现异常的确切时间,但我看不到确切的原因。是由于 MaxReceivedMessageSize 还是类似的原因。

是不是 traces.svclog 不能包含此类信息,还是我做错了什么?

如何获得这些信息?

已编辑(添加):

来自我的服务器端 app.config:

    <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="NAVBinding_ICustomer_Service"
                closeTimeout="01:50:00"
                openTimeout="01:50:00" receiveTimeout="01:50:00" sendTimeout="01:50:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
                maxReceivedMessageSize="2147483647" messageEncoding="Text"
                textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service name = "Customer_Service"  behaviorConfiguration="returnFaults">
            <endpoint name="NAVBinding_ICustomer_Service"
               address  = "http://localhost:8000/nav/customer"
               binding  = "basicHttpBinding"
               bindingConfiguration= "NAVBinding_ICustomer_Service"
               contract = "NAVServiceReference.ICustomer_Service"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="returnFaults" >
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
 </system.serviceModel>

已编辑(添加):

将 WCF 服务从“黑匣子”转变为易于排除故障的服务的正确和最佳方法是什么? 您使用哪些工具和技术对 WCF 服务进行故障排除?

【问题讨论】:

  • 它应该在您的跟踪日志中,您要发送什么大小的文件?
  • 文件大小约为 8 MB。实际上就是通过 XML 流传输的数据库表数据的大小,所以我不知道数据流的最终确切大小,可能包括 XML 标记信息。但它肯定比 MaxReceivedMessageSize 参数的默认 65536 大。
  • 你能告诉我们服务器 app.config( 部分)吗?您使用 WCF 流式传输(例如,返回类型为 Stream 的方法)还是缓冲传输(默认)??
  • 我已将服务器 app.config 添加到我的问题内容中。考虑 WCF 流式传输 - 我的服务合同方法都没有返回类型为“Stream”(它们大多具有“someArray[]”返回类型)。
  • 我的秘密正在客户端上跟踪...

标签: wcf web-services connection trace


【解决方案1】:

忽略 maxRequestLength 的问题(其他人已经回答), 我将尝试回答您关于如何对 WCF 进行故障排除的原始问题。

如果您已经在使用服务跟踪查看器(我无法从问题中看出 如果您只是手动查看它们) - 可能所有细节都不是 进入文件。

当我想获得真正的硬核时,我会启用所有日志记录参数 消息记录。 (这会生成一些大的服务日志,所以不要离开 它打开)

 <system.serviceModel>
  <diagnostics>
   <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="-1" />
  </diagnostics>
 </system.serviceModel>

如果您不使用 Microsoft 服务跟踪查看器,我建议您这样做。它 提供我需要的所有信息来追踪那些棘手的消息握手,消息 大小异常等。这是 MSDN 参考,可帮助您入门 http://msdn.microsoft.com/en-us/library/aa751795.aspx

存在潜在问题的跟踪交互在 左上角的详细窗格通常会突出显示异常 红色的服务事件。有时你会遇到多个问题作为内在 错误通过服务堆栈级联 - 但您可以在 跟踪查看器。

如果您在服务器的“服务日志”中一无所获,那么您的异常可能完全在客户端 - 理论上您可能会超出某些客户端 在任何消息实际到达之前的侧安全参数(消息大小等) Web 服务端 - 但客户端问题通常更容易追踪,因为您知道您只需要担心在客户端编辑配置文件(即不是因为客户端和服务器设置之间的任何交互)。

【讨论】:

  • +1 用于屏幕截图和对服务跟踪查看器的引用,它基本上是摇滚。
【解决方案2】:

在过去 2 天多的时间里,我一直在试图找出为什么我得到“底层连接已关闭:连接意外关闭”的原因,方法调用返回了更多数据,而没有太多数据(即,它适用于仅返回较小的数据集)。

我的错误信息略有不同(可能是由于框架差异),但想分享我发现的原因。首先,我想说的是,虽然在上面给出的答案中跟踪和增加配置文件中某些内容的大小可能有助于跟踪 WCF 错误,但这些内容并不能帮助我确定错误的真正原因。

通过查看抛出的异常并沿链向上,我可以看到以下根错误: “现有连接被远程主机强行关闭” - 这是 System.Net.Sockets.SocketException

然后调用链向上是: “无法从传输连接读取数据:现有连接被远程主机强行关闭。” - System.IO.IOException,然后

“底层连接已关闭:接收时发生意外错误。” - System.Net.WebException,最后是捕获的异常的消息,

“接收对 的 HTTP 响应时发生错误。这可能是由于服务端点绑定未使用 HTTP 协议。这也可能是由于 HTTP 请求上下文被服务器中止(可能是由于服务关闭)。有关更多详细信息,请参阅服务器日志。” - 一个 System.ServiceModel.CommunicationException

启用跟踪然后使用 TraceViewer 查看跟踪日志确实使这更容易查看,但从未告诉我“现有连接被远程主机强制关闭”错误的真正原因。

就我而言,我的 WCF 服务托管在 IIS6 上,只有当我联系负责这些服务器的机构支持并要求他们查看系统事件日志时,我才立即看到答案 - System.OutOfMemoryException!

我的 WCF 服务在分配的 200MB RAM 中运行,而我的方法消耗的内存不止于此。我查看了我的方法,最终发现了一个应该在它所在的块(循环)之外/之下的代码块。 ..所以我的方法中生成了指数类型的集合。

希望这对其他人有所帮助。

【讨论】:

    【解决方案3】:

    回答您的问题,如何创建一个容易解决问题的 WCF 服务。一种方法是尽量减少潜在错误的数量,从而减少故障排除时需要查看的内容。

    有两个主要的错误来源:

    • 由于配置错误
    • WCF 服务引发的异常

    配置错误通常是由于客户端和服务不匹配造成的。为了避免这种情况,所有可能的配置都放在 BindingConfiguration 中,并在客户端和服务器上复制并使用它。我认为这实际上是您的问题所在,您正在更新服务 web.config,其中的内容也需要在客户端配置中。例如最大大小,或者在一个中缓冲并在另一个中流式传输。

    服务抛出的错误应作为 FaultException 抛出,并在 Contract 中定义为 FaultContract

    对于剩余的错误,您需要查看其他帖子中描述的 trace.svclog 文件。您还需要查看事件日志和 IIS 日志,调用可能在到达 WCF 服务之前被阻止。

    【讨论】:

      【解决方案4】:

      尝试设置maxRequestLength 属性:

      <system.web>
          <httpRuntime maxRequestLength="2147483647" />
      </system.web>
      

      【讨论】:

      • 我已经尝试过(只是将您的代码添加到服务器 app.config),但发生的情况没有明显的变化。
      • 您是否有机会将traces.svclog 文件上传到某处以便我们查看?
      【解决方案5】:

      对于仍然遇到此问题的任何人 - 像往常一样,上述讨论中遗漏了一些绝对重要的事情,没有这些事情就没有找到答案的希望。这就是我花了 3 个小时在网上寻找答案的原因。

      回顾一下: 首先,我从 Silverlight 服务中使用 WCF 得到了可怕的 Not Found 错误。不,这不是因为找不到服务。我能够通过调用的服务方法清楚地完成,包括返回。然后客户端在调用的异步结束部分出现异常。没有解释。它与绑定等无关。

      然后我发现了类似这样的关于使用跟踪查看器的论坛消息。原来我已经配置好了,但没有得到任何跟踪(所以我认为我的服务必须没问题,尤其是因为我可以通过跟踪)。错了,邦戈男孩。然后我发现另一条消息说一个鲜为人知的事实是,如果您设置跟踪侦听器以写入“C:\logs\mylog”,则必须首先手动创建 C:\logs。它不会为你做这件事。

      好的,现在我得到日志并在 TraceViewer 中显示它。因此,我收到有关未终止字符串的“错误消息”。 30 分钟后,我发现另一条消息说,哦,每个人都知道你必须先结束本地开发服务器才能清除最后的消息。你知道,那些真正告诉你出了什么问题的人吗?

      现在我了解真正的错误并查看其中的每一个:抛出异常、RequestContext 中止和无法通过 http 发送响应消息。只有第一个很重要。当然,除了在查看下部窗格时,它根本没有给我任何有用的信息,只是说存在序列化错误。嗯,“哪里”会很好。

      不知所措,我突然注意到下部窗格中有一个小 XML 选项卡,就在“格式化”选项卡旁边。当我点击它时,对于我的 ThrowingAnException 消息,它就是 - 一个巨大的转储,其中包含非常具体的消息,导致我直接解决了问题:

      System.ServiceModel.CommunicationException,System.ServiceModel,版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089 尝试序列化参数时出错:GetTimecardsWithAlertsResult。 InnerException 消息为“枚举值 '0”对于类型“Timeclock.Web.ShiftManager.AlertType”无效并且无法序列化。如果类型具有 DataContractAttribute 属性,请确保存在必要的枚举值并使用 EnumMemberAttribute 属性进行标记。'。有关详细信息,请参阅 InnerException。

      问题是我没有初始化一个类的基于枚举的成员,所以它是 0,这不是我允许的枚举值之一。很容易修复。

      很明显,微软很容易检测到,因为他们成功地将大量信息隐藏了 3 个小时。

      这是 Microsoft 的一个想法 - 您是否提供一种方法来捕获这些错误和最重要的异常消息服务器端?还是让它们完全传递给 Silverlight 客户端?您知道吗,为了便于查看发生了什么,我可以在 3 秒内解决这个简单的问题,而不是在 3 小时内因无用而向客户收费?

      哦,我知道了。这真的很难,因为它是通过 http 进行的异步调用,而卑鄙的互联网会伤害你的大脑。但猜猜怎么了?你是微软。你有无限的时间和金钱。你影响了数百万人。当你搞砸这种垃圾时,就像你在成千上万个你无法被打扰的场景中做的那样,你会影响全球成千上万的开发人员。

      在 StackOverflow 上环顾四周。看看全球有多少人,聪明的人试图编写软件来做有用的重要事情,他们只是没有沉浸在上述令人难以置信的细节中,因为你知道,他们有真正的工作要做。

      将我在这个愚蠢问题上的 3 小时乘以数以万计的开发人员在典型的一年中经历 30 到 40 集这种废话,你就会看到你造成了什么灾难。可以说“这就是我们获得大笔报酬的原因”,但想想如果我们每次转身都不必潜入 3 小时* *你为我们挖的洞?

      微软,你对编程不利,对业务不利,对人类不利。我不在乎有多少台计算机运行您的软件。你需要做得更好。请开始表现得像你了解你在世界上、每个国家、每一天对勤奋工作的奴才有多少虐待。如果你只是表现得像把事情做对很重要,你能让一个地方变得更好。

      蒂姆·约翰逊

      【讨论】:

      • 你知道,这里不是咆哮的地方,但我必须承认我有同样的感觉......我不记得我在 WCF 跟踪上浪费了多少小时。不得不学习配置xml文件以生成日志以在图形工具中打开,只是因为枚举中没有命名零?给我一个例外!
      【解决方案6】:

      您应该在客户端获得特定的通信异常。 我认为您所描述的这个异常是在客户端出现故障后尝试重用客户端后引发的异常。

      试试这个:

      1. 在服务器端配置文件集 includeExceptionDetailInFaults="true"
      2. 当您使用客户端时,不要使用“使用模式”。查看this 文章。

      我认为您不需要追踪。试试上面的方法,你就能看到确切的通信错误了。

      哦,顺便说一句,您的客户端是 Silverlight 应用程序吗? 如果是这样,那就有点复杂了...查看this 文章。

      【讨论】:

      • 不,它不是 Silverlight,它是 WPF 应用程序
      • 事实上,我的服务器 app.config 文件中包含 includeExceptionDetailInFaults="true" ,但它无助于获取断开连接的原因。也许我设置不正确。
      猜你喜欢
      • 1970-01-01
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多