WCF跟踪。我如何得到关闭连接的确切原因?

时间:2009-12-19 19:49:34

标签: wcf web-services connection trace

在我的WCF服务中,尝试传输大数据时,我不断收到错误: 基础连接已关闭:连接意外关闭

我想知道是什么原因引发了这个错误,所以我设置了 WCF跟踪并且可以读取 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服务问题?

6 个答案:

答案 0 :(得分:26)

忽略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

具有潜在问题的跟踪交互以黄色突出显示 向左,右上角的详细窗格通常会显示异常 红色服务活动。有时你会得到多个内心的问题 错误通过服务堆栈级联 - 但你可以在中看到它 跟踪查看器。

Troubleshooting Using the Service Trace Viewer

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

答案 1 :(得分:7)

我花了最近2天的时间试图找到为什么我得到“底层连接已关闭:连接意外关闭”,方法调用返回时有更多数据,而不是那么多数据(即,只有返回较小的数据集才能正常工作。

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

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

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

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

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

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

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

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

希望这可以帮助别人。

答案 2 :(得分:2)

回答您的问题如何创建易于故障排除的WCF服务。一种方法是尽可能减少潜在错误的数量,以便在排除故障时查看的内容较少。

有两个主要的错误来源:

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

配置错误通常是由于客户端和服务之间不匹配造成的。为了避免这种情况,可以在BindingConfiguration中进行所有配置,并在客户端和服务器上复制并使用它。我认为这实际上是你的问题所在,你正在更新服务web.config,还需要在客户端配置中。对于eaxmple最大大小,或者在一个中缓冲,在另一个中流式传输。

服务引发的错误应该作为FaultException抛出,并在合同中定义为FaultContract

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

答案 3 :(得分:1)

尝试设置maxRequestLength属性:

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

答案 4 :(得分:1)

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

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

然后我发现了关于使用跟踪查看器的论坛消息。事实证明我已经配置了,但没有得到任何痕迹(所以我认为我的服务必须是好的,特别是因为我可以追踪通过)。错,邦戈男孩。然后我发现另一条消息说一个鲜为人知的事实是,如果你设置一个跟踪监听器来写“C:\ logs \ mylog”,你必须先手动创建C:\ logs。它不会为你做。

好的,现在我获取日志并将其提交到TraceViewer中。于是我收到一条关于未终止字符串的“错误消息”。三十分钟后,我发现另一条消息说,哦,每个人都知道你必须先结束你的本地开发服务器才能清除最后的消息。你知道吗,实际上告诉你出了什么问题的那些?

现在我找到真正的错误并查看其中的每一个:抛出异常,RequestContext中止,以及通过http发送响应消息失败。只有第一个才重要。当然,除了查看下部窗格外,它没有给我任何有用的信息,只是说有序列化错误。嗯,“哪里”会很好。

在我结束时,我突然注意到下方窗格中有一个小的XML选项卡,紧邻“格式化”选项卡。当我点击它时,对于我的ThrowingAnException消息,它就是 - 一个带有高度特定消息的巨大转储,这使我正确地解决了问题:

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

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

显然,微软很容易发现,因为他们成功地将大量信息隐藏在窥探眼睛3小时之内。

这是Microsoft的一个想法 - 您如何提供一种方法来捕获这些错误以及最重要的异常消息服务器端?或者让他们完全传递给Silverlight客户端?你知道,为了让你很容易看到发生了什么,所以我可以在3秒内修复这个简单的问题,而不是3小时我必须向我的客户收取任何无用的费用?

哦,我知道。这真的很难,因为它是对http的异步调用,并且平均互联网会让你的大脑受到伤害。但猜猜怎么了?你是微软。你有无限的时间和金钱。而你影响了数百万人。当你用这种方式搞砸时,就像你在成千上万无法打扰的场景一样,你会影响全球数十万的开发者。

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

在这个愚蠢的问题上花费我3个小时的时间,成千上万的开发人员在一般的一年里会花30到40集这类垃圾,你会看到你所造成的灾难。可以说“这就是我们为此付出巨额代价”的原因,但想想如果我们每次转身,我们都可以在世界上实现什么样的实际工作,我们不必潜入3小时的时间* *你为我们挖洞吗?

微软,你不喜欢编程,不利于商业,也不利于人类。我不关心有多少台计算机运行你的软件。你需要做得更好。请开始表现得像你了解你在世界各地,每个国家,每一天都滥用顽固分子的人数。如果你只是采取行动来做正确的事情,你可以做得多好一点。

蒂姆约翰逊

答案 5 :(得分:0)

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

试试这个:

  1. 在服务器端配置文件集includeExceptionDetailInFaults =“true”
  2. 当您使用客户端时,请不要使用“使用模式”。查看this文章。
  3. 我认为你不需要追踪。尝试以上操作,您将能够看到确切的通信错误。

    哦,BTW是你的客户端是Silverlight应用程序吗? 如果是这样,那就更复杂了......看看this文章。