WCF连接重置:需要重新启动服务器

9
这个问题与在Windows Server 2003上托管的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的请求,但没有写入任何日志。从视觉角度来看,这是不响应与正常图形之间的区别。 non-responding - 对比 - enter image description here 有人能建议比重新启动服务器更温和的解决方案吗?显然,已经尝试过重启主机服务(以及其他系统服务,如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)
-------------------------------------------------------

1
所有这些事件的上下文是什么?也许 serviceHost 没有被收集,因为事件处理程序保留了一个引用。如果你确实需要它们,请确保在关闭之前执行 -= - Crowcoder
@Crowcoder 问题已经编辑,包括了处理程序的示例:它们只是简单地写入日志文件。但请注意,我还激活了更详细的WCF跟踪... - user6250137
@Crowcoder,非常感谢你的帮助,但请注意,WCF停止响应的同时,元数据WSDL请求也会停止响应,这与我的处理程序无关,它完全是标准的,只能通过跟踪来捕获...顺便说一句,当我重新启动服务时,即使它不响应,Windows服务重启也会在日志中被正常跟踪... - user6250137
很可能您正在遇到某些节流限制(由于某些导致会话/实例无法关闭的错误)。您的节流配置是什么?https://msdn.microsoft.com/zh-cn/library/ms731379(v=vs.110).aspx。尝试将节流值设置得非常低,然后进行一些调用,看看是否可以重现您的问题。还应检查 Windows 日志中来自 WCF 的消息 - 当达到这些限制时,它应该进行跟踪。 - Evk
Windows事件日志中有什么信息吗?当发生这种情况时,“Net.Tcp Listener Adapter”服务的状态是什么? - JAZ
显示剩余3条评论
4个回答

1

潜在问题

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

无响应的WCF只是在这种情况发生之前发送的早期消息。

事实上,以下是内存泄漏的典型症状:

您仍然可以ping服务器,并且它仍然会处理一些基本命令,如关闭命令,但它不允许浏览文件或文件夹,您也无法远程桌面连接到服务器。

您有几个工具可用于监视:

  • 进程资源管理器
  • poolmon

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

附注

您还可以检查\System32\LogFiles\HTTPERR下的http日志。

可能需要应用热补丁


好的。从错误日志HTTP API中可以看出,Connections_Refused的存在表明http.sys已停止接收新连接,因为NonPagedPool内存已降至限制以下。 - user6996876

1
这是一个针对旧版 .Net 4.0 的 WCF 线程池的错误。你可以在这里这里找到一些参考资料。
你应该将服务账户从本地系统移动到本地服务。这是保留 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服务中的线程操作(如DB访问等)。

相关问题

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

技术公告:高负载运行后WCF服务可能变得无响应

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

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

故障排除:连接被强制关闭

原因:

有问题的网络硬件正在丢弃部分TCP流量

或者

SynAttackProtect设置可能会断开连接。

查看以下注册表可能会证明有用

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

以下文章提到了两个原因:

0

你是否在使用服务时消耗了服务? 请记得在消耗服务的任何地方(甚至是在服务器端)关闭连接。

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

使用指令 PerRequest 检查你的 ServiceHost 销毁情况,以便监视服务主机实例的处理是否被允许,以及代码其他部分是否存在硬引用,从而防止 Gcollected。

我认为你可能已经达到了最大连接数。


0

我以前在旧版本的Windows上使用Web服务时,遇到过关于MemoryStream和Binary Writers的奇怪问题。从来没有什么道理,不知道是硬件限制还是某种奇怪的.Net bug。也许尝试将Stream从using块中取出,并使用Try-Finally语句处理它。在以前遇到的二进制写入问题中,我不得不自己处理,而且效果很好。就像"using"块在完成之前试图关闭一切一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接