【问题标题】:WCF connection reset: server reboot neededWCF 连接重置:需要重新启动服务器
【发布时间】:2016-08-20 14:40:39
【问题描述】:

此问题与 Windows Server 2003 上的 Windows 服务中托管的 WCF 有关。

在正确工作几天后会出现此问题,并且只能通过重新启动服务器来解决。

C# 代码在其日志中未捕获任何异常

serviceHost.Opening += new EventHandler(serviceHost_Opening);
serviceHost.Opened += new EventHandler(serviceHost_Opened);
serviceHost.Closing += new EventHandler(serviceHost_Closing);
serviceHost.Closed += new EventHandler(serviceHost_Closed);
serviceHost.Faulted += new EventHandler(serviceHost_Faulted);
serviceHost.UnknownMessageReceived += new EventHandler<UnknownMessageReceivedEventArgs>(serviceHost_UnknownMessageReceived);

serviceHost.Open();

处理程序是这样实现的:

 void serviceHost_Opened(object sender, EventArgs e)
{ 
    CentralReport.MyService.SrvLog("WinCentralRpt",String.Format("service opened by sender: {0}", sender.GetType().ToString()));
}

void serviceHost_Opening(object sender, EventArgs e)
{
    CentralReport.MyService.SrvLog("WinCentralRpt",String.Format("service opening by sender: {0}", sender.GetType().ToString()));
}    

public static void SrvLog(string user, string line) {
    string log_path = System.Configuration.ConfigurationManager.AppSettings["srv_log"];
    if (log_path != null) {
        using (System.IO.StreamWriter logSW = new System.IO.StreamWriter(
            log_path.Replace("{user}",user.ToLower()),true)) {
            logSW.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss tt", CultureInfo.InvariantCulture) + ": " + line);
        }   
    }
}

在客户端,C# WCF 使用者在调用操作后正确关闭连接。

已激活最高级别跟踪。

   <system.diagnostics>
      <sources>
            <source name="System.ServiceModel" 
                        switchValue="All"
                        propagateActivity="true">
                <listeners>
                        <add name="xml" />
                </listeners>
             </source>
            <source name="CardSpace"
                        switchValue="All">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
            <source name="System.IO.Log"
                        switchValue="All">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
            <source name="System.Runtime.Serialization"
                        switchValue="All">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
            <source name="System.IdentityModel"
                        switchValue="All">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging"
                        switchValue="All">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
            <source name="System.ServiceModel.Activation"
                        switchValue="All">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
      </sources>

        <sharedListeners>
            <add name="xml"
                 type="System.Diagnostics.XmlWriterTraceListener"
                 initializeData="C:\MyPath\Traces.svclog" />
        </sharedListeners>
<trace autoflush="true" />
   </system.diagnostics> 

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

    <serviceBehaviors>
        <behavior name="MyServiceBehavior">
            <dataContractSerializer maxItemsInObjectGraph="6553500"/>
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
    </serviceBehaviors>

操作系统检查似乎没问题

netstat -ao | grep 9nnn
tasklist /SVC | grep Opxxx

我的感觉是通道侦听器无法正常工作,但跟踪日志中没有显示任何问题。 服务器只是停止响应对此 WCF 的请求,但从那一刻起它不会向日志写入任何内容。 从视觉的角度来看,这里是无响应与正常图。

- 与 -

有人可以提出比重新启动服务器更温和的解决方案吗?显然,已经尝试重新启动主机服务(以及其他系统服务,如 dns 和 ipsec),甚至重新安装了 WCF。只有重新启动服务器才能解决问题。

知道根本原因是什么吗?

编辑 - 重启后

重新启动后 - 没有任何其他更改 - WCF 再次开始工作。

旁注

还有一个小问题,我不完全理解。 现在运行 - 当一切正常时 - 命令

httpcfg.exe query urlacl 

那是windows 2003版本的

netsh http show urlacl

我本来希望看到 WCF url,但输出只是(为什么?)

C:\>httpcfg.exe query urlacl
    URL : http://+:80/Temporary_Listen_Addresses/
    ACL : D:(A;;GX;;;WD)
-------------------------------------------------------

【问题讨论】:

  • 所有这些事件的背景是什么?也许serviceHost 没有被收集,因为事件处理程序保留了一个引用。如果您真的需要它们,请确保在关闭前-=它们。
  • @Crowcoder 问题已编辑以包含处理程序的示例:它们只是编写一个日志文件。但也请考虑我已经激活了更详细的 wcf 跟踪...
  • 好吧,我不知道。我会说尝试运行 ANTs 分析器并使用日志库或队列中介使您的日志线程安全。
  • @Crowcoder 我很感激,非常感谢,但请注意 wcf 也停止响应与我的处理程序无关的元数据 wsdl 请求,它是完全标准的,它应该只被捕获跟踪...顺便说一句,当我重新启动服务时,即使它没有响应,Windows 服务重新启动也会在日志中定期跟踪...
  • 很可能你达到了一些油门限制(因为一些阻止会话/实例关闭的错误。你的油门配置是什么?msdn.microsoft.com/en-us/library/ms731379(v=vs.110).aspx。尝试将油门值设置得非常低,然后让一些调用,看看你是否可以重现你的问题。还要检查来自 wcf 的消息的 Windows 日志 - 它应该在达到这些限制时进行跟踪。

标签: c# wcf windows-server-2003


【解决方案1】:

我之前在旧版本的 Windows 上使用 Web 服务的 MemoryStream 和 Binary Writers 遇到过奇怪的问题。没有任何意义,不知道这是硬件限制还是一些奇怪的一次性 .Net 错误。也许尝试将 Stream 从 using 块中拉出并在 Try-Finally 情况下处理它。在过去与二进制编写器有关的问题时,我必须自己处理它并且它工作得很好。几乎就像“使用”块试图在完成之前关闭所有内容一样。

【讨论】:

    【解决方案2】:

    您是否正在使用您的服务中的服务? 请记住在您使用服务的任何地方(即使在服务器端)关闭连接。

    您可能知道在 WCF 中存在一个 ChannelFactory,该工厂为您提供服务代理,但它也是一个 ICommunicationObject,您必须释放该服务代理实例才能关闭连接。

    使用指令 PerRequest 检查您的 ServiceHost 销毁,以监控是否允许处置服务主机实例,以及是否存在不允许 Gcollected 的代码的其他部分中的硬引用。

    我认为您可能已经用完了最大连接数。

    【讨论】:

      【解决方案3】:

      这是旧的 .Net 4.0 版本的 WCF 线程池中的一个错误。 您可以找到一些参考资料herehere

      您应该将服务帐户从本地系统移动到本地服务。这是为本地服务帐户保留 URL 的 windows 2003 命令。

      httpcfg set urlacl /u http://+:9nnn/Your/Url/ /a "D:(A;;GX;;;LS)"
      

      此外,您可以只启用 WCF 性能计数器并关闭 WCF 跟踪。

      <system.serviceModel>
        <diagnostics performanceCounters="All" />
        ...
      

      它们将显示在性能监视器的 Service.ModelService 类别下。

      总之,将 WCF 服务中的线程操作(如数据库访问等)替换为单独的进程或不同的(非 WCF)辅助服务。

      相关问题

      类似的问题已在全球范围内记录

      Technical Bulletin: WCF 服务在高负载运行后可能会变得无响应

      如果出现症状,请重新启动托管无响应的服务器 服务。

      一个有趣的 msdn 建议可能适合这里

      疑难解答:Connection Forcibly Closed

      原因:

      有故障的网络硬件正在丢弃部分 TCP 流量

      SynAttackProtect 设置可能会断开连接。

      查看以下注册表可能很有用

      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
      

      以下article 提到了两个原因:

      • 操作系统的 TCP 缓冲区内存不足
      • 操作系统用完了可用的 TCP “临时”端口(@98​​7654326@ 指的是上述注册表 tcp/ip parameters

      【讨论】:

        【解决方案4】:

        根本问题

        这是一个非分页池资源问题。

        无响应的 WCF 只是一个早起的消息,在此发生之前发送。

        确实,以下是内存泄漏的典型症状

        您仍然可以 ping 服务器,它仍然处理一些基本的 命令,如关机命令,但它不允许浏览 文件或文件夹,并且您无法 RDP 到服务器。

        你有几个工具可以监控它:

        • 进程浏览器
        • 池蒙

        阅读PearmanRussinovich 的这两篇文章以获得完整指导。

        旁注

        也可以查看\System32\LogFiles\HTTPERR下的http日志。

        有一个可能的hotfix 被应用。

        【讨论】:

        • 对。从Error logging HTTP APIs可以看出,Connections_Refused的存在证明http.sys已经停止接收新的连接,导致NonPagedPool内存降到了限制以下。
        猜你喜欢
        • 2011-04-21
        • 1970-01-01
        • 1970-01-01
        • 2016-07-23
        • 2013-06-25
        • 2012-05-03
        • 1970-01-01
        • 2019-07-12
        相关资源
        最近更新 更多