我們有一個c#web服務和客戶端,都是在Visual Studio 2008(新項目 - > ASP.Net Web服務應用程序)中創建的。服務託管在Windows Server 2012 R2,IIS 8.5上。winsock資源不足
當客戶端將數據發送到我們的服務時,我們將其轉發給第三方服務,將結果保存到數據庫並將其返回給客戶端。
問題在於,在極少數情況下,當我們的服務處於沉重負載(每秒很多請求)時,它開始拋出'可用於完成套接字連接啓動的不足的winsock資源'。
我們發現我們的Web服務正在打開許多到第三方服務的TCP連接,並將它們保持在TIME_WAIT狀態。當這樣的連接數量達到很高的數量(大約17000)時,整個服務器就失去了建立新連接的能力。從遠程桌面到互聯網瀏覽器的所有內容停止工作。這會持續幾分鐘,然後,當Windows開始關閉這些連接時,它會正常恢復。
對於與第三方服務的通信,我們的服務在其整個生命週期中僅使用一個SoapClient實例。它在初始化時創建,並且永遠不會關閉或銷燬;新的實例永遠不會被創建。
BLIND.BLINDSoapClient client = new BLIND.BLINDSoapClient(base.binding, base.address);
當數據發送到第三方服務,我們簡單地調用它的Web方法,並把它像沒有關閉,出售或做任何清理:
BLIND.Answer answer = client.Search(...);
..save to database
return answer;
有什麼我們可以做些什麼來避免time_wait連接的這種構建?
有更好的方法來管理SoapClient(s)嗎?我們是否應該爲每個請求打開一個新的soap客戶端並手動關閉它們?
如果是相關的,這裏是如何我們結合設置:
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;
謝謝!
當我們添加對第三方Web服務的引用時,它是由visual studio創建的類。右鍵單擊服務引用 - >添加服務參考 – dbrckovi