線索是進一步讀入錯誤消息並發現以下:
(provider:TCP提供,錯誤:0 - 每個套接字地址中的一個使用量(協議/網絡地址/端口)通常是允許的。)
最常見的原因是應用程序未使用連接池。 你們都知道如何合併工作,但如果你不這樣做,簡短的版本是開放和關閉連接是昂貴的。 因此,當您使用連接池並關閉連接時,它並未真正關閉。 相反,它被放入一個游泳池和一個新的連接打開時,則不會創建一個新的連接,而是從池中挑選和「激活」。
現在,如果您不使用連接池,則會創建一個新的連接,並在關閉時將其處置並放入池中。 爲什麼這很重要? 那麼,打開連接時,客戶端將打開一個套接字(或端口),以便與服務器進行通信。 現在,當連接關閉時,端口未關閉,而是進入所謂的TIME_WAIT以等待可能延遲或錯誤路由的包等。 端口在TIME_WAIT中的默認值爲240秒(4分鐘),在此期間,該端口不可用。 這意味着,TIME_WAIT狀態中一個新的連接不能使用此端口,以及一個新的將被打開。
如果您在Windows 2003安裝上運行應用程序,則可以使用的端口數爲1024到5000,這意味着大約有4000個端口可用。 多見於: 「TCP TIME-WAIT延遲」 http://msdn2.microsoft.com/en-us/library/ms819739.aspx
那麼,請問這是怎麼結合在一起? 在上述情況下,假設你有1000名員工或用戶,他們都來自午餐回來,他們坐了下來,他們所使用的Web應用程序 爲用戶帶來了4條記錄每個。 每個記錄的檢索需要1秒。現在,如果您使用上述信息,並做數學題你就會明白,1000個用戶* 4米的連接將 打開4000個端口運行的Web應用程序,這是限制在機器上。現在,所有這些端口將處於TIME_WAIT狀態4分鐘 ,在此期間,任何新的連接不能打開,你會得到上述錯誤。 4分鐘後,端口釋放,用戶可以再次連接。
但是,如果使用連接池,這不會發生,因爲連接未關閉,因此它不會將端口置於TIME_WAIT。
在.Net應用程序中,默認情況下,池應該處於ON狀態,但它可能已在連接字符串中被禁用(或設置爲false)。 所以,簡單地看看連接字符串,並相應地改變它:
// Pooling false = fails
string cs = @"Data Source=tcp:<your server>;Integrated Security=True;Pooling=false";
// Pooling true = works, this is the default but included here for clarity
string cs = @"Data Source=tcp:<your server>;Integrated Security=True;Pooling=true";
閱讀邁克爾的博客上MSDN Blogs。
較舊的程序員在連接無法打開並重新啓用連接時會禁用連接池。不知道爲什麼。 – 2011-03-28 23:23:18
大開眼界!謝謝 – 2011-03-28 23:25:57
如果未在連接字符串中指定池,則其默認值爲true。然後我不應該得到這個錯誤。但我得到這個錯誤。另外,在Michael的博客中唯一的評論中,評論者說:「將連接設置爲pooling = true後,幾乎所有頁面的加載時間也大大減少。」我是否需要明確指定pooling = true? – shashi 2011-05-24 09:50:45