httpclient4.5.5 PoolingHttpClientConnectionManager

    今天在作騰訊網址安全檢測API接入時用到了org.apache.httpcomponents.httpclient-4.5.5這個包,當初在main方法裏測試的時候發現從請求到響應大概要用0.6s的時間,可是在springboot應用裏面使用的時候,第一次請求用了0.4s左右,第二次就只要0.1s左右,很驚訝,而後想是否是鏈接池的做用,查找過程以下:html

    1.首先在本地,在將程序運行起來後先不進行請求,使用 jmap -histo:live 19144 > d://a.txt 命令(參考https://www.cnblogs.com/anjijiji/p/6239395.html)將JVM中存活的全部對象打印到文件中,在文件中查看是否存在org.apache.http開頭包名的類,發現找不到。spring

    2.使用postman進行一次API請求,而後在使用 jmap -histo:live 19144 > d://a.txt 將文件覆蓋後進行查看,發如今文件中找到幾個關於org.apache.http.impl.conn開頭的幾個類,將有關鏈接池的類列出以下:apache

    org.apache.http.impl.conn.CPooljson

    org.apache.http.impl.conn.CPoolEntry安全

    org.apache.http.impl.conn.PoolingHttpClientConnectionManagerspringboot

 

    PoolingHttpClientConnectionManager是一個HttpClientConnection的鏈接池封裝,能夠爲多線程提供併發請求服務。主要做用就是分配鏈接,回收鏈接等,同一個route的請求,會優先使用鏈接池提供的空閒長鏈接;CPoolEntry是ManagedHttpClientConnection的封裝,包含具體的一個鏈接的信息;CPool是繼承AbstractConnPool的一個鏈接池實現,PoolingHttpClientConnectionManager在進行具體的分配鏈接,回收鏈接獲時實際上調用的是CPool。服務器

    

    只介紹cpool幾個屬性(供參考):多線程

        routeToPool: 具體的路由粒度對應的鏈接池併發

        leased:    已經被租用的鏈接(正在被使用的)app

        available:    空閒鏈接

        pending:    正在等待獲取鏈接隊列

        maxPerRoute:    每一個路由上最大的鏈接數(不能超過鏈接池總鏈接數)

        defaultMaxPerRoute:    默認的每一個路由上最大的鏈接數(不能超過鏈接池總鏈接數)

        maxTotal:    鏈接池最大的鏈接數

        validateAfterInactivity:空閒永久鏈接檢查間隔,這個牽扯的還比較多官方推薦使用這個來檢查永久連接的可用性,而不推薦每次請求的時候纔去檢查(ms)

   3.在知道以上的原理以後,下面列出具體配置代碼(歡迎指出錯誤和共同交流!)

public class UrlUtil {
    public static final Logger logger = LoggerFactory.getLogger(UrlUtil.class);

    private static CloseableHttpClient httpClient = null;//
    static {
        PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager();
        clientConnectionManager.setValidateAfterInactivity(2000);//檢測有效鏈接的間隔
        clientConnectionManager.setMaxTotal(50);//設定鏈接池最大數量
        clientConnectionManager.setDefaultMaxPerRoute(50);//設定默認單個路由的最大鏈接數(因爲本處只使用一個路由地址因此設定爲鏈接池大小)
        httpClient = HttpClients.createMinimal(clientConnectionManager);
    }

    /**
     * 檢測URL安全,騰訊網址安全API(部分代碼)
     * @param urlString
     * @return
     * @throws Exception
     */
    public static void urlSafe(String urlString) throws Exception {

        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost("http://www.cloud.urlsec.qq.com");
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(1000)//設定鏈接服務器超時時間
                    .setConnectTimeout(1000)//設定從鏈接池獲取可用鏈接的時間
                    .setSocketTimeout(1000)//設定獲取數據的超時時間
                    .build();
            httpPost.setConfig(requestConfig);
            HttpEntity entity = new StringEntity(params,"utf-8");
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-type", "application/json");
            response = httpClient.execute(httpPost);
        } catch (Exception e) {
            throw e;
        }finally {
            if (null != response) {
                response.close();
            }
        }
    }

}

參考文章:https://www.cnblogs.com/shoren/p/httpclient-leaseConnection.html

相關文章
相關標籤/搜索