1

我有一个 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

我已将 SessionMode 设置为 NotAllowed 并将绑定更改为流式传输。

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

4

4 回答 4

2

根据您的描述,似乎:1.最初客户端能够毫无问题地连接到您的服务器,因此这排除了配置问题2.一段时间后服务器停止响应,但您没有说多长时间,多大是请求率,以及服务器是完全停止响应,还是只是间歇性地响应。基于此,一种可能性是服务器端出现问题。你注意到服务器端有什么异常吗?要寻找的东西是:

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

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

您的服务器程序需要检测客户端是否中止了连接,然后立即 close() 以释放端口。如何?请参阅读取()。在读取文件结尾(意味着收到 FIN)时,返回零。

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

任何 WCF 通道都实现ICommunicationObject,它为通道生命周期提供事件。

您应该收听 Faulted 事件 sessionId 可以像往常一样从 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_WAIT,直到无法操作

于 2013-10-11T20:09:23.270 回答
0

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

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

  2. 将 receiveTimeout 设置为较低的值以验证这是问题所在。

于 2013-10-08T16:38:25.130 回答
0

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

于 2013-10-14T21:21:38.543 回答