HttpWebRequest多執行緒效能問題,請求超時的錯誤
轉自:http://hi.baidu.com/ju_feng/blog/item/b1c41dbf09ad9e0119d81fb0.html
透過Netstat –abn | find “:443” 如果有兩個Time_Wait 和CLOSE_WAIT狀態的網路連線,則該服務就不可用
解決方法:
1 HttpWebRequest的預設連線只有兩個,因此在多執行緒併發的情況下只有兩個併發請求
可以透過 System.Net.ServicePointManager.DefaultConnectionLimit = 20
設定網路HttpWebRequest的網路連線池的個數
2 HttpWebRequest 的請求因為網路問題導致連線沒有被釋放則會佔用連線池中的連線個數,導致並非連線數量減少
可以透過如下方法來修改此問題 :
2.1 給ServicePointManager設定KeepLive檢測,在網路沒有響應的情況下關閉該連線
System.Net.ServicePointManager.SetTcpKeepAlive(true, _keepLiveTime, _intervalTime);
3 定時檢測HttpWebRequest的ServicePoint的健康狀況
//ServicePoint point = webReq.ServicePoint;
//string connectionsGroupName = webReq.ConnectionGroupName;
//if (point != null)
//{
// if (point. > 15)
// point.CloseConnectionGroup(connectionsGroupName);
//}
4 使用HttpWebRequest 一定要保證GetRequestStream和GetResponse物件關閉,否則容易造成連線處於CLOSE_WAIT狀態
using (Stream stream = webReq.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
}
HttpWebResponse response = null;
try
{
response = webReq.GetResponse() as HttpWebResponse;
}
finally
{
try
{
if (response != null)
response.Close();
//ServicePoint point = webReq.ServicePoint;
//string connectionsGroupName = webReq.ConnectionGroupName;
//if (point != null)
//{
// if (point. > 15)
// point.CloseConnectionGroup(connectionsGroupName);
//}
}
catch
{
}
}
I am wondering whether there is a way to handle broken (or better: closed) TCP connections that reside in the connection pool (ServicePoint) used by a HttpWebRequest instance. What I have seen on Windows 2003 Server systems is that under certain circumstances, all sockets used to connect to a web service are in CLOSE_WAIT state and all subsequent HttpWebRequests fail with a timeout, no new connections to the web service were opened. Looking at the problem with WireShark, I couldn't see any HTTP traffic even though the application kept on making requests that all ended in a timeout.
I have tried to reproduce this behaviour on a development system by writing a simple HTTP server that closes the socket after it has sent a proper HTTP 1.1 response. If you do this, you will see the same behavior that I have described above. Of course, HTTP 1.1 assumes that by default connections are kept alive unless the server explicitly sends a "Connection: Close" header. Thus, the client-side would assume that the connection should be kept alive although the server (that does not function according to HTTP 1.1) already closed it. What stuns me is that the HttpWebRequest, or more specifically the ServicePoint does not recover from such a situation (on Windows Vista/2003 Server the client-side sockets stay in CLOSE_WAIT until they're killed by the OS, on another development machine running the Windows 7 RC they're killed by the OS rather quickly and are just gone, no new ones will be created in either case).
I have tried various things on the client-side, so far I could not solve this problem (except by disabling keep alive in each HttpWebRequest by setting the "KeepAlive" property to "false"). The following list compiles what I've tried to recover from the situation described above:
- Various combinations of using() blocks to dispose all resources (WebResponse object, stream retrieved by GetResponseStream(), StreamReader that was used to read from the stream), as well as using the WebResponse.Close() method call that do everything required from my understanding of the MSDN documentation.
- Calling CloseConnectionGroup() on the ServicePoint used by the HttpWebRequest to somehow "kill" the connections
- Temporarily disabling keep alives to recover
- Increasing the number of connections in the pool of the ServicePoint so that it doesn't stop the system from functioning properly if some connections die
- Enabling TCP keep alives on the ServicePoint
- Using a lower ConnectionLeaseTimeout on the ServicePoint (works correctly in general, fails to do anything when connections are closed)
Thus, I'd like to ask here whether someone faced similar problems and might know a way to overcome such issues. I'd also like to know whether I am hunting ghosts here, although I still doubt it at the moment. I also don't see how a socket could get into a CLOSE_WAIT state without the remote communication partner closing the connection (i.e. sending FIN) and I don't understand why Vista/2003 Server do not seem to respond to this by sending a FIN and receiving an ACK to transition from CLOSE_WAIT to LAST_ACK and then to CLOSED. The HTTP server I wrote does not tinker with the LingerState of the TcpClient, default behavior should apply when it comes down to gracefully closing sockets.
Maybe I am missing some very important point about this whole thing, I'd love to be enlightened :-). If you need any further info, I'm happy to supply it.
PS: I have done all of my tests in Visual Studio 2008 linking both .NET 2.0 and .NET 3.5, it doesn't make a difference from what I can tell.
Cheers!
HTTP連線狀態:
// //伺服器開通KeepLive. 第一個引數是客戶端開啟Keeplive,
// //第二個引數是客戶端是否關閉網路連線
////Server: Close_Wait Client:Fin_Wait_2
//HttpRequestTest.TestHttpConnect(false, false);
////Server: Close Client: Time_Wait
//HttpRequestTest.TestHttpConnect(false, true);
////Server: ESTABLISHED Client: ESTABLISHED
//HttpRequestTest.TestHttpConnect(true, true);
//Server: Close Client: Time_Wait
// HttpRequestTest.TestHttpConnect(false, true);
//伺服器關閉KeepLive. 第一個引數是客戶端開啟Keeplive,
//第二個引數是客戶端是否關閉網路連線
////Server: Close_Wait Client:Fin_Wait_2
//HttpRequestTest.TestHttpConnect(false, false);
////Server: Close Client: Time_Wait
//HttpRequestTest.TestHttpConnect(false, true);
////Server: Close Client: Time_Wait
//HttpRequestTest.TestHttpConnect(true, true);
////Server: Close Client: Time_Wait
//HttpRequestTest.TestHttpConnect(false, true);
REF:
http://www.cnblogs.com/zealic/archive/2008/05/01/1107942.html
[@more@]來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/310974/viewspace-1043123/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 大請求、請求超時問題
- 多執行緒引起的效能問題分析執行緒
- 請教一個多執行緒的問題執行緒
- iOS 多網路請求的執行緒安全iOS執行緒
- Faiss使用多執行緒出現的效能問題AI執行緒
- 多執行緒問題執行緒
- 請教一個事務+多執行緒 的問題執行緒
- java多執行緒執行問題Java執行緒
- 多執行緒鎖的問題執行緒
- 請教一個多執行緒的問題--wait多個鎖執行緒AI
- HttpWebRequest請求http1.1的chunked的解析問題記錄HTTPWeb
- 請教大俠。關於多執行緒同步問題執行緒
- Java多執行緒面試高配問題---多執行緒(3)🧵Java執行緒面試
- 多執行緒程式設計,處理多執行緒的併發問題(執行緒池)執行緒程式設計
- 多執行緒問題解釋執行緒
- 多執行緒相關問題執行緒
- Hibernate 多執行緒問題!執行緒
- 多執行緒-多執行緒常見的面試題執行緒面試題
- Java多執行緒中執行緒安全與鎖問題Java執行緒
- seam中使用多執行緒的問題執行緒
- 一個多執行緒的PushbackInputStream問題執行緒
- 請教 做多執行緒 、快取最佳化速度的問題執行緒快取
- java多執行緒問題 多核cpu遇上java多執行緒,求解釋Java執行緒
- 請教一個多執行緒編寫的題!執行緒
- 多執行緒之8鎖問題執行緒
- 05.java多執行緒問題Java執行緒
- 多執行緒下的程式同步(執行緒同步問題總結篇)執行緒
- 【java 多執行緒】多執行緒併發同步問題及解決方法Java執行緒
- 多執行緒應用–Http請求阻塞回撥處理執行緒HTTP
- 多執行緒應用--Http請求阻塞回撥處理執行緒HTTP
- 執行緒安全-一個VC下多個網路請求執行緒
- BATJ都愛問的多執行緒面試題BAT執行緒面試題
- 多執行緒的安全性問題(三)執行緒
- objective-c 多執行緒注意的問題Object執行緒
- 解決POI多執行緒匯出時資料錯亂問題執行緒
- 請教一個關於執行緒的問題執行緒
- 多執行緒-執行緒安全問題的產生原因分析以及同步程式碼塊的方式解決執行緒安全問題執行緒
- 請教執行錯誤提示