1. 程式人生 > >發起http請求之HttpClient 關於(發生一個或多個錯誤) 的問題

發起http請求之HttpClient 關於(發生一個或多個錯誤) 的問題

很多 sof 設置 mic 大並發 關於 manage 使用 發生

最近項目遇到一個問題,同樣的程序,再本地調試跑沒問題,但是放到服務器上跑,卻會出現各種超時。

查了查日誌,發現多數是這樣的一個錯誤

message:發生一個或多個錯誤。

經過一步步排查發現是HttpClient發送請求時的錯誤,我本地請求一個接口6分鐘能收到結果,但是在服務器上,1個小時後就返回了這麽個錯誤

查閱了很多文檔資料。

才知道是httpclient在並發線程時,出現的異常。

httpclient在處理請求連接方面使用了連接池,它內部實際上有兩種連接池,一種是全局的ConnectionPool,一種是每主機(per-host)HostConnectionPool。參數maxHostConnections就HostConnectionPool中表示每主機可保持連接的連接數,maxTotalConnections是ConnectionPool中可最多保持的連接數。每主機的配置類是HostConfiguration,HttpClient有個int executeMethod(final HostConfiguration hostConfiguration, final HttpMethod method)方法可以指定使用哪個HostConfiguration,不過多數情況都是不顯示指定HostConfiguration,這樣httpclient就用了默認的HostConfiguration=null,也就是說所有的請求可以認為指自同一個主機。如果不設置這兩個參數,httpclient自然會用默認的配置,也就是MultiThreadedHttpConnectionManager中的:

public static final int DEFAULT_MAX_HOST_CONNECTIONS = 2; 
// Per RFC 2616 sec 8.1.4 ? public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20;

使用httpclient還有兩點經驗,一個是創建的MultiThreadedHttpConnectionManager 實例最好是全局的,否則會有多個連接池,而HttpClient是線程安全的,可以多個實例。另一個是,在處理請求的最後,也就是finnaly裏中,要調用method.releaseConnection();回收連接,否則連接池就可能會爆了。

PoolingClientConnectionManager conMgr = new PoolingClientConnectionManager();

conMgr.setMaxTotal(200); //設置整個連接池最大連接數 根據自己的場景決定

//是路由的默認最大連接(該值默認為2),限制數量實際使用DefaultMaxPerRoute並非MaxTotal。

//設置過小無法支持大並發(ConnectionPoolTimeoutException: Timeout waiting for connection from pool),路由是對maxTotal的細分。

conMgr.setDefaultMaxPerRoute(conMgr.getMaxTotal());//(目前只有一個路由,因此讓他等於最大值)

//另外設置http client的重試次數,默認是3次;當前是禁用掉(如果項目量不到,這個默認即可)

httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));

此處解釋下MaxtTotal和DefaultMaxPerRoute的區別:

1、MaxtTotal是整個池子的大小;

2、DefaultMaxPerRoute是根據連接到的主機對MaxTotal的一個細分;比如:

MaxtTotal=400 DefaultMaxPerRoute=200

而我只連接到http://www.baidu.com時,到這個主機的並發最多只有200;而不是400;

但素。

.net 中httpclient是4.5後才出來的,

而.net 的HttpClientHandler.MaxConnectionsPerServer 是4.7.1後才出現的,

所以在.net4.7以前想要適應多線程,需要自己處理了。。。

參考文檔:

https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.maxconnectionsperserver?view=netframework-4.8#System_Net_Http_HttpClientHandler_MaxConnectionsPerServer

     https://news.cnblogs.com/n/553217/

     https://bbs.csdn.net/topics/390257271

     https://www.cnblogs.com/gisblogs/p/4201096.html

     https://blog.csdn.net/kobejayandy/article/details/16921265

     https://blog.csdn.net/fgx_123456/article/details/78206001

這裏還有dudu寫的一個可以提高httpclient性能的相關測試

http://www.cnblogs.com/dudu/p/csharp-httpclient-attention.html

發起http請求之HttpClient 關於(發生一個或多個錯誤) 的問題