我有一个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
};
UPDATE2
我已将SessionMode设置为NotAllowed并将绑定更改为流式传输。
我可以做些什么来提高性能或找出问题?
答案 0 :(得分:2)
从你的描述看来,似乎:1。最初客户端能够连接到你的服务器没有问题,所以这排除了配置问题2.一段时间服务器停止响应,但你没说多久,请求率有多大,服务器是否完全停止响应,或者只是间歇性响应。基于这种可能性是服务器端出现问题。您是否注意到服务器端有什么异常?要寻找的是:
答案 1 :(得分:0)
听起来你的客户永远不会断开连接。
您确定您的客户正在关闭频道吗?请注意,您应该调用ChannelFactory.Close,而不仅仅是Dispose。
将receiveTimeout设置为低,以验证这是问题所在。
答案 2 :(得分:0)
您的客户端通过调用close()来关闭连接,后者将FIN发送到服务器套接字,服务器套接字确认FIN并且其状态现在已更改为CLOSE_WAIT,并保持该状态,除非服务器发出close()调用插座。
您的服务器程序需要检测客户端是否已中止连接,然后立即关闭()以释放端口。怎么样?请参阅read()。在读取文件结尾(意味着收到FIN)时,返回零。
您可以检测客户端是否已断开连接。
任何WCF渠道都会实施 ICommunicationObject ,它会为渠道生命周期提供事件。
你应该听Faulted事件 可以从OperationContext.Current属性一直访问sessionId。 当您的客户打开频道时(在第一次操作时),注册适当的事件:
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事件,在意外发生时会出现故障(如网络故障)。
查看以下链接..它的类似。它帮助了我..
TCP Socket Server Builds Up CLOSE_WAITs Occasionally Over Time Until Inoperable
答案 3 :(得分:0)
验证路由器不是问题,因为某些消费级路由器对允许的开放套接字/连接数有限制。