日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

httpclient連接池管理,你用對了?

 

一、前言

為何要用http連接池那?因為使用它我們可以得到以下好處:

因為使用它可以有效降低延遲和系統開銷。如果不采用連接池,每當我們發起http請求時,都需要重新發起Tcp三次握手建立鏈接,請求結束時還需要四次揮手釋放鏈接。而鏈接的建立和釋放是有時間和系統開銷的。另外每次發起請求時,需要分配一個端口號,請求完畢后在進行回收。

使用鏈接池則可以復用已經建立好的鏈接,一定程度的避免了建立和釋放鏈接的時間開銷。

二、連接池使用

public static void init() {
    //1.創建連接池管理器
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(60000,//1.1
            TimeUnit.MILLISECONDS);
    connectionManager.setMaxTotal(1000);//1.2
    connectionManager.setDefaultMaxPerRoute(50);//1.3
    
    //2.創建httpclient對象
    httpClient = HttpClients.custom()
            .setConnectionManager(connectionManager)//2.1
            .disableAutomaticRetries()//2.2
            .build();
}

如上代碼1,我們創建了一個連接池管理器,
ClientConnectionPoolManager會維護每個路由維護和最大連接數限制。默認情況下,此實現將為每個給定路由創建不超過2個并發連接,并且總共不超過20個連接。對于許多現實應用程序,這些限制可能證明過于嚴格。但是,我們可以自由來調整連接限制。

另外構造函數中可以設置持久鏈接的存活時間TTL(timeToLive),其定義了持久連接的最大使用時間,超過其TTL值的鏈接不會再被復用。

如上代碼1.1我們設置TTL為60s(Tomcat服務器默認支持保持60s的鏈接,超過60s,會關閉客戶端的鏈接)。代碼1.2我們設置連接器最多同時支持1000個鏈接,代碼1.3設置每個路由最多支持50個鏈接。注意這里路由是指IP+PORT或者指域名。如果使用域名來訪問則每個域名有自己的鏈接池,如果使用IP+PORT訪問,則每個IP+PORT有自己的鏈接池。

如上代碼2我們基于連接池管理器創建了一個httpClient對象,下面我們就可以使用它發起http請求了。

CloseableHttpResponse response = null;
try {
    
    //3.創建請求對象
    final HttpGet httpGet = new HttpGet("http://127.0.0.1:8080/test");
    
    RequestConfig.Builder builder = RequestConfig.custom();
    builder.setSocketTimeout(3000)//3.1設置客戶端等待服務端返回數據的超時時間
           .setConnectTimeout(1000)//3.2設置客戶端發起TCP連接請求的超時時間
           .setConnectionRequestTimeout(3000);//3.3設置客戶端從連接池獲取鏈接的超時時間
    httpGet.setConfig(builder.build());

    //4.發起請求
    response = httpClient.execute(httpGet);

    //5.成功則解析結果
    if (200 == response.getStatusLine().getStatusCode()) {
        String strResult = EntityUtils.toString(response.getEntity());
        System.out.println(strResult);
    }

} catch (ClientProtocolException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    //5.回收鏈接到連接池
    if (null != response) {
        try {
            EntityUtils.consume(response.getEntity());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如上代碼3創建了一個HttpGet對象,并創建RequestConfig對象來設置請求參數。

代碼3.3設置客戶端從連接池獲取鏈接的超時時間,如果在該時間內沒能從連接池獲取到連接,則拋出
ConnectionPoolTimeoutException異常。

代碼3.2設置客戶端發起TCP連接請求的超時時間,也就是創建TCP連接時候等待的時間,如果該時間內還沒完成TCP三次握手,則拋出ConnectTimeoutException異常。

代碼3.1設置客戶端等待服務端返回數據的超時時間,也就是請求發出去后,如果等待該時間服務端還沒返回結果,則拋出SocketTimeoutException異常。

代碼4則發起http請求,代碼5發現請求OK,則使用自帶工具類EntityUtils.toString解析返回值(內部讀取流結束后,會自動返還鏈接到連接池)

代碼5則當請求結束后做一個兜底鏈接歸還(如果返回狀態值不是200,則需要在這里處理鏈接歸還),注意這里不能調用response.close();因為其不是歸還鏈接到連接池,而是關閉鏈接。

三、總結

本文簡單介紹了如何使用鏈接池,使用連接池時需要注意合理設置最大鏈接數和每個路由(比如域名)對應的鏈接數,另外特別需要注意設置
setConnectionRequestTimeout參數,其決定了從連接池拿鏈接的超時時間。

另外需要注意使用鏈接池時,請求結果回來后,要記得歸還鏈接,如果鏈接得不到歸還,則首先會把連接池打滿,然后新來的請求從連接池拿不到鏈接會拋出
ConnectionPoolTimeoutException異常。

另外歸還鏈接不要調用response對象的close()方法,因為其是關閉鏈接,而不是把鏈接返回到鏈接池。需要調用EntityUtils中方法或者自己從response.getEntity().getContent()獲取流,讀取完畢(讀取完畢后會自動歸還鏈接)或者不讀取時主動調用流的close()來顯示歸還鏈接到連接池。

知識擴展:自http1.1后,http默認支持keep-alive。對于Tomcat服務器默認保持客戶端的鏈接60s,我們httpclient這邊也可以設置鏈接存活時間,最終鏈接的存活時間是取兩者中最小的。

對于過期鏈接的處理,當Tomcat主動關閉鏈接時,httpclient 4.4之前是每次在復用鏈接前進行檢查鏈接是否可用,http4.4后,是自上次使用連接以來所經過的時間超過已設置的超時時(默認超時設置為2000ms),才檢查連接。如果發現鏈接不可用,則從鏈接池剔除,在創建新的鏈接。

當客戶端設置的TTL到期時(此時Tomcat容器沒有主動關閉鏈接時),在每次發起請求時,會檢查鏈接是否已經過期,如果過期(雖然鏈接本身是可以用的),則也主動關閉鏈接,然后從鏈接池剔除,在創建新的鏈接。

另外我們可以實現自己的
ConnectionKeepAliveStrategy來給不同的域名設置不同的鏈接存活策略。

分享到:
標簽:httpclient
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定