與 SQL Server 建立連接時出現與網絡相關的或特定於實例的錯誤。未找到或無法訪問服務器。請驗證實例名稱是否正確並且 SQL Server 已配置為允許遠程連接。 (provider: TCP Provider, error: 0 - 由於系統緩沖區空間不足或隊列已滿,不能執行套接字上的操作。)。
1 命令行下輸入 netstat -ano >>D://net.txt ,列出目前端口使用情況,如下大概有三千多條 ,注意紅色端口的使用
TCP 222.122.222.222:2756 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2766 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2776 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2786 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2796 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2806 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2816 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2828 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2838 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2851 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2860 52.122.120.88:80 CLOSE_WAIT 2144
TCP 222.122.222.222:2870 52.122.120.88:80 CLOSE_WAIT 2144
.......
發現本地在訪問一個外網地址的80端口,對應PID是2144
這里可以直接到任務管理器里面查看PID對應進程
2.命令行下輸入 tasklist|findstr "2144" 查看 PID對應的進程
w3wp.exe 2144 services
3.命令行下輸入 C:\Windows\System32\inetsrv>appcmd list wp
WP "5648" (applicationPool:testmozhou)
WP "5664" (applicationPool:tqh.xxx.cn)
WP "1544" (applicationPool:www.lxxxg.com)
WP "2144" (applicationPool:data.tt.com)
確認問題來源,webservice多線程下,每個httpwebrequest沒有及時釋放問題所致
PS:
最近事情很多,人也懶,東西看了不少,也想到過一些東西,但就是懶得寫。現在記錄一下前兩個星期做一個壓力測試時出現的現象,希望重開一個好頭。簡單地說,這是個從Windows Server連接Linux下的MongoDB服務時出現的問題。MongoDB使用的是自定義的二進制協議,客戶端使用普通的TCP連接進行連接后再讀寫數據。在以前的測試中,我使用的都是建立少量連接,每個連接進行多次操作,而這次則是對“應用程序”進行壓力測試,因此需要不斷地開啟及關閉連接——頻率大約是每秒4、500次吧。
我使用的環境是Windows Web Server 2008 R2,MongoDB部署在Cent OS上,雙方都是64位操作系統。壓力測試剛開啟時一切順利,性能也比較令人滿意,但是不久后便會拋出這樣的異常:
由於系統緩沖區空間不足或隊列已滿,不能執行套接字上的操作。
一開始我以為是程序里有哪個地方沒有釋放連接,於是檢查了程序代碼,覺得沒有問題;后來又直接使用mongodb-csharp進行頻繁連接關閉,結果還是出現了同樣的錯誤,於是我又懷疑是驅動本身的問題,但是看了看討論組中似乎又沒有人匯報過這個問題;於是我又換了個思路,使用了Java平台上的驅動寫了個簡單的測試程序,居然還是得到了這個錯誤。由此我確定了兩點:
- 這很可能不是mongodb-csharp這個驅動程序的問題。當然,要確定這一點還需要更多測試,例如在mono上使用這個驅動。
- 這是操作系統方面的問題,因為.NET和Java都給出了同樣的錯誤信息,甚至和當前程序的語言文化設置無關。
還有一個細節:在直接使用驅動進行插入操作的時候,發現無論使用多少線程同時進行,最終永遠是在插入了16370-16380條記錄之后停止,這意味着每次都是打開關閉了確定次數之后出現的錯誤,這很有可能是一個操作系統限制所致的結果。因此,我使用這段錯誤信息在網上尋找解決方案,原因有很多,大都不是我需要的。順便一提,只有中文的錯誤信息真是很難找到合適的結果,因此我不得不通過幾個關鍵字,再連蒙帶猜地得到了錯誤的標准英文翻譯:
An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
有了這段信息,找起答案來就簡單多了,例如KB上找到了這樣一條記錄,說是在Windows Vista及2008中,Tcp/IP動態端口的范圍調整到49152至65535,做一個簡單的減法可以發現我們可以使用16384個接口,和我們之前看到的記錄數量大致相同,基本可以確定是頻繁地打開關閉操作造成客戶端的動態端口用盡的問題。KB上也給出了解決方法,只要使用netsh命令便可以進行設置。
不過有意思的是,我在此之前還找到了另一條記錄,說是在HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters下面可以增加一個MaxUserPort參數,指定程序可以使用的端口范圍,它的默認值是5000,也就是端口范圍是1025至5000,這也是上一條記錄中說Windows之前的端口策略,它的“適用范圍”已經不包括2008系統,但我鬼使神差地將MaxUserPort設置為65534(十進制)之后,原本只能插入16000多條記錄的程序已經能夠插入數萬條,這意味着修改的確生效了。
當然,這么做還是沒有解決問題,總不見得插入這么多條記錄之后還是失敗吧。其實第二條記錄里還寫到,有一個TcpTimedWaitDelay參數,表示一個關閉后的端口等待多久之后可以重新使用,順着這個信息我找到了《TCP/IP Registry Values for Windows Server 2008》這樣一篇文章,描述Vista與2008系統中各種TCP/IP相關的參數,其中自然包括了TcpTimedWaitDelay,它的默認值為120,表示端口關閉后120秒才能重新使用。
於是我們來算一下,假設有60000個端口可用,如果在120秒內消耗完畢,則每秒最多使用500個端口,這遠遠低於MongoDB的性能瓶頸,甚至接近了一個Web應用程序的需求——根據壓力測試,我們單台Web服務器每秒可以處理接近200個動態請求,這意味着平均每個請求只能使用2.5個連接。根據文檔,我將TcpTimedWaitDelay設成最短的30秒,這意味着我們可以每秒開啟關閉2000個端口,平均每個請求使用10個連接。夠了。
這個問題就這樣解決了,說實話很簡單,也就是個“知道就能解決”的配置問題。當然現在這個方式並不算太理想,更好的方式應該是利用連接池,這樣便不會開啟/關閉大量的TCP/IP連接,默認的端口數量也已經足夠了,更重要的是這也可以省下很大的開銷——因為經過測試,即使是最復雜的ASP.NET頁面,只要不涉及MongoDB,每秒也能處理6500多個請求,而目前每秒200個動態請求,從數字上看也遠低於MongoDB的能力,我們有理由相信目前的性能似乎是卡在連接的打開/關閉上了。
只可惜目前mongodb-csharp的連接池實現有bug,用於清理連接的維護進程居然會讓造成明顯的中斷,甚至在頻繁使用十幾分鍾后還拋出了異常。有機會的話我再看看吧,但我總覺得它目前的實現過於復雜了,我估計都可以說是面向對象的“經典”使用案例了。
最后再來一提,話說我目前使用的是64位的Windows Web Server 2008 R2系統,功能強大,價格便宜,授權寬松,最多允許使用到32GB內存,作為Web服務器我很滿意。
PS:文章只做個人保存學習使用
轉自:http://www.360doc.com/content/15/0414/10/22908209_463085108.shtml