服务变得无响应,许多套接字处于CLOSE_WAIT状态



我有一个WCF服务,其中有一个NetTcpBinding,运行着大约100个客户端。客户端定期从服务器轮询信息,一段时间后服务不再响应。

查看 netstat,我可以看到许多处于CLOSE_WAIT状态的连接。

这是我的绑定:

<netTcpBinding>
  <binding  name="default" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxConnections="10000">
    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
  </binding>
</netTcpBinding>

我还尝试将 closeTimeout 的值从默认值 00:01:00 更改为 00:00:10,但没有效果。

该机器是Windows Server 2008 R2 64位。

更新:

我现在添加了一个ServiceThrottlingBehavior,但结果仍然是一样的。

new ServiceThrottlingBehavior
{
 MaxConcurrentCalls = 1000,
 MaxConcurrentInstances = 1000,
 MaxConcurrentSessions = 1000
};

更新2

我已将会话模式设置为不允许,并将绑定更改为流式处理。

任何想法我可以做些什么来提高性能或找出问题?

从您的描述来看,似乎:1.最初客户端能够毫无问题地连接到您的服务器,因此这排除了配置问题2。过了一会儿,服务器停止响应,但你没有说请求速率有多长,以及服务器是完全停止响应,还是只是间歇性响应。基于这种可能性,服务器端出了问题。您是否注意到服务器端有任何异常?要寻找的东西是:

  1. 线程计数 -- 是所描述的线程池(作为某些设置可以在线程池线程上设置上限(?特别是尝试全新发布并观察线程计数,直到它停止回应,有什么模式吗?你可能有死锁,很长阻塞操作等,使线程保持时间过长。
  2. 内存 -- 内存泄漏有问题吗?
  3. 它是自托管服务吗?您是否有适当的代码来捕获 ServiceHost.Faulted 事件(和重新启动服务(?如果服务主机出现故障,它将不会响应到任何请求。
  4. 查看 WCF 性能计数器告诉您的内容,尤其是队列大小和活动连接数。从性能计数器中,你将知道服务是否正在接受任何请求,或者你的限制是否配置是必要的。
  5. 终极诊断工具:启用服务端 WCF 跟踪?打开跟踪文件将一定要告诉你请求发生了什么。如果您看到任何异常 在跟踪文件中,您将找到根本原因。

听起来您的客户永远不会断开连接。

  1. 您确定您的客户正确关闭了频道吗?请注意,您应该调用 ChannelFactory.Close,而不仅仅是 Dispose。

  2. 将接收超时设置为低值以验证这是问题所在。

您的客户端通过调用 close(( 关闭连接,这会将 FIN 发送到服务器套接字,该套接字确认 FIN 及其状态现在更改为 CLOSE_WAIT,并且除非服务器在该套接字上发出 close(( 调用,否则保持这种状态。

您的服务器程序需要检测客户端是否已中止连接,然后立即关闭((以释放端口。如何?请参考 read((。读取文件末尾(意味着收到 FIN(后,返回零。

您可以检测客户端是否已断开连接。

任何WCF通道都实现ICommunicationObject,它提供通道生存期的事件。

您应该侦听故障事件会话 ID 可以像往常一样从 OperationContext.Current 属性访问。当客户端打开通道(在第一个操作上(时,注册到足够的事件:

OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted);
OperationContext.Current.Channel.Closed += new EventHandler(Channel_Faulted);

void Channel_Faulted(object sender, EventArgs e)
 {
     Logout((IContextChannel)sender);
 }
 protected void Logout(IContextChannel channel)
 {
        string sessionId = null;
        if (channel != null)
        {
            sessionId = channel.SessionId;
        }
 }

如果套接字已断开连接,则应收到通道故障事件。当客户端正常关闭时,将引发 Closed 事件,当意外关闭时(如网络故障(,将引发 Faulted。

查看以下链接..它有点相似.它帮助了我..

TCP 套接字服务器偶尔会随着时间的推移CLOSE_WAITs累积,直到无法运行

验证路由器不是问题,因为某些消费级路由器对允许的开放套接字/连接数有上限。

最新更新