zoukankan      html  css  js  c++  java
  • HttpClient4.5.2 连接池原理及注意事项

    随着微服务的流行,服务之间的http调用越来越多,遇到的问题也比较多,写这边文章的目的也是将自己遇到的坑和解决方案跟大家分享

    一、为什么要用Http连接池

    1、降低延迟:如果不采用连接池,每次连接发起Http请求的时候都会重新建立TCP连接(经历3次握手),用完就会关闭连接(4次挥手),如果采用连接池则减少了这部分时间损耗,别小看这几次握手,本人经过测试发现,基本上3倍的时间延迟

    2、支持更大的并发:如果不采用连接池,每次连接都会打开一个端口,在大并发的情况下系统的端口资源很快就会被用完,因为TCP请求大部分都是在很短时间内内结束,每个连接关闭之后都有一个TIME_WAIT, 如果并发很大,TIME_WAIT会导致连接又不能及时关闭,短时间内就会消耗掉大量端口(一个TCP连接Client占用一个端口),而单机的端口是有限的,端口消耗完之后不能建立新连接

    二、代码

    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集合

    本着人人为我,我为人人的思想,第一次写技术博客,欢迎大家提出有建设性的意见。

  • 相关阅读:
    0302 随想
    1231递归下降语法分析程序设计
    《构建之法》1、2、3章读后感
    复利计算总结
    操作系统实验0
    学习进度条
    0302思考并回答一些问题
    评论
    c语言文法
    词法分析
  • 原文地址:https://www.cnblogs.com/likaitai/p/5431246.html
Copyright © 2011-2022 走看看