不足的Winsock资源 [英] Insufficient winsock resources

查看:3313
本文介绍了不足的Winsock资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个C#的Web服务和客户端,无论是在Visual Studio 2008中创建(新项目 - > ASP.Net Web服务应用程序)。服务托管在Windows Server 2012 R2,IIS 8.5。

We have a c# web service and client, both created in Visual Studio 2008 (new project -> ASP.Net web service application). Service is hosted on Windows server 2012 R2, IIS 8.5.

在客户端发送数据到我们的服务,我们把它转发给第三方服务,其结果保存到数据库中,并返回给客户端。

When the client sends the data to our service, we forward it to a 3rd party service, save the result to a database and return it to the client.

问题是,在某些罕见的情况下,当我们的服务是重负载(每秒许多要求)下,它开始抛出无法完成socket连接初始化Winsock的不足的资源。

The problem is that, in some rare occasions, when our service is under heavy load (many requests per second), it starts throwing 'Insufficient winsock resources available to complete socket connection initiation'.

我们发现,我们的Web服务是开放给第三方服务多个TCP连接,并让他们在TIME_WAIT状态。当这样的连接数达到高数(约17000),其全部服务器失去使任何新的连接的能力。从远程桌面到互联网浏览器都停止工作。这个持续几分钟,然后,视窗开始关闭这些连接时,就恢复正常。

We found that our web service is opening many TCP connections to 3rd party services, and leaving them in TIME_WAIT state. When the number of such connections reaches a high number (around 17000), the entire server loses ability to make any new connections. Everything from remote desktop to the internet browser stops working. This lasts for a few minutes, and then, when Windows begins closing those connections, it resumes normally.

有关与第三方服务的沟通,我们的服务是通过其整个生命时间只用一个SoapClient的实例。它是在初始化创建,并且永远不会关闭或销毁;新的实例永远不会创建。

For communication with the 3rd party service, our service is using only one SoapClient instance through its entire life time. It is created on initialization, and is never closed or destroyed; new instances are never created.

BLIND.BLINDSoapClient client = new BLIND.BLINDSoapClient(base.binding, base.address);

在将数据发送到第三方服务,我们简单地调用它的Web方法,并把它像没有关闭,出售或做任何清理:

When sending the data to the 3rd party service we simply call its web method, and leave it like that without closing, disposing or doing any clean-up:

BLIND.Answer answer = client.Search(...);
..save to database
return answer;

时有什么我们可以做,以避免TIME_WAIT连接的这种积聚?

Is there anything we can do to avoid this build-up of time_wait connections?

有没有更好的方式来管理SoapClient的(S)?我们是否应该打开一个新的SOAP客户端为每一个请求,然后手动关闭它们?

Is there a better way to manage SoapClient(s)? Should we open a new soap client for every request and close them manually?

如果它是相关的,这里是我们如何结合设置:

If it is relevant, here is how our binding is set up:

      binding = new BasicHttpBinding();
      binding.Name = "SLTDSoap";
      binding.CloseTimeout = TimeSpan.FromSeconds(Timeout);
      binding.OpenTimeout = TimeSpan.FromSeconds(Timeout);
      binding.ReceiveTimeout = TimeSpan.FromSeconds(Timeout);
      binding.SendTimeout = TimeSpan.FromSeconds(Timeout);
      binding.AllowCookies = false;
      binding.BypassProxyOnLocal = false;
      binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
      binding.MaxBufferSize = 65536;
      binding.MaxBufferPoolSize = 524288;
      binding.MessageEncoding = WSMessageEncoding.Text;
      binding.TextEncoding = System.Text.Encoding.UTF8;
      binding.TransferMode = TransferMode.Buffered;
      binding.UseDefaultWebProxy = true;

      binding.ReaderQuotas.MaxDepth = 32;
      binding.ReaderQuotas.MaxStringContentLength = 8192;
      binding.ReaderQuotas.MaxArrayLength = 16384;
      binding.ReaderQuotas.MaxBytesPerRead = 4096;
      binding.ReaderQuotas.MaxNameTableCharCount = 16384;

      binding.Security.Mode = (_url.StartsWith("https:")) ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.None;
      binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
      binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
      binding.Security.Transport.Realm = "";
      binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
      binding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Default;

System.Net.ServicePointManager.DefaultConnectionLimit = 500;

感谢您!

推荐答案

我想我们可能已经解决了'winsock的资源不足的问题。

I think we might have solved the 'insufficient winsock resources' problem.

我们已经设置了以下注册表键值:
HKEY_LOCAL_MACHINE \\系统\\ CurrentControlSet \\服务\\ TCPIP \\参数\\ MaxUserPort的= 60000
HKEY_LOCAL_MACHINE \\系统\\ CurrentControlSet \\服务\\ TCPIP \\参数\\ TcpTimedWaitDelay的= 30

We have set the following registry values: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\MaxUserPort = 60000 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\TcpTimedWaitDelay = 30

在偷看倍的生产环境我们的最大预期负载为每秒150个请求。
这意味着,我们将创建在30秒内连接4500,Windows之前开始释放他们。
这远低于60000,并应确保此问题不会再次发生。

Our maximum expected load on production environment at peek times is 150 requests per second. This means we'll create 4500 connections in 30 seconds, before windows starts releasing them. This is well below 60000, and should ensure this problem doesn't happen again.

我们在离开每秒150请求,3天以上这些设置运行的系统,并没有发生问题。

We left the system running at 150 requests per seconds with these settings over 3 days, and the problem didn't happen.

这篇关于不足的Winsock资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆