httpclient連接池


HttpClient4.5.2 連接池原理及注意事項

 

隨着微服務的流行,服務之間的http調用越來越多,遇到的問題也比較多,寫這邊文章的目的也是將自己遇到的坑和解決方案跟大家分享

一、為什么要用Http連接池

1、降低延遲:如果不采用連接池,每次連接發起Http請求的時候都會重新建立TCP連接(經歷3次握手),用完就會關閉連接(4次揮手),如果采用連接池則減少了這部分時間損耗,別小看這幾次握手,本人經過測試發現,基本上3倍的時間延遲

2、支持更大的並發:如果不采用連接池,每次連接都會打開一個端口,在大並發的情況下系統的端口資源很快就會被用完,導致無法建立新的連接

二、代碼

1、HttpConnectionManager.java連接池管理類,支持https協議

@Component

public class HttpConnectionManager {

    PoolingHttpClientConnectionManager cm = null;
    
    @PostConstruct
    public void init() {
        LayeredConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        cm =new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(200);
        cm.setDefaultMaxPerRoute(20);
    }

    public CloseableHttpClient getHttpClient() {       
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .build();          
        
        /*CloseableHttpClient httpClient = HttpClients.createDefault();//如果不采用連接池就是這種方式獲取連接*/
        return httpClient;
    }
}

2、連接池消費類:HaoMaiClient.java

@Component
public class HaoMaiClient {
    @Autowired
    HttpConnectionManager connManager;
    
    public <T> T get(String path,Class<T> clazz){
        CloseableHttpClient httpClient=connManager.getHttpClient();
        HttpGet httpget = new HttpGet(path);
        String json=null;        
        CloseableHttpResponse response=null;
        try {
            response = httpClient.execute(httpget);
            InputStream in=response.getEntity().getContent();
            json=IOUtils.toString(in);
            in.close();
        } catch (UnsupportedOperationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {            
            if(response!=null){
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            }            
        }                
        return JSON.parseObject(json, clazz);
    }

}

三、原理及注意事項

連接池中連接都是在發起請求的時候建立,並且都是長連接

HaoMaiClient.java中的in.close();作用就是將用完的連接釋放,下次請求可以復用,這里特別注意的是,如果不使用in.close();而僅僅使用response.close();結果就是連接會被關閉,並且不能被復用,這樣就失去了采用連接池的意義。

連接池釋放連接的時候,並不會直接對TCP連接的狀態有任何改變,只是維護了兩個Set,leased和avaliabled,leased代表被占用的連接集合,avaliabled代表可用的連接的集合,釋放連接的時候僅僅是將連接從leased中remove掉了,並把連接放到avaliabled集合中

本着人人為我,我為人人的思想,第一次寫技術博客,歡迎大家提出有建設性的意見。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM