2.http连接池只适用于请求是经常访问同一主机(或同一个接口)的情况下
3.并发数不高的情况下资源利用率低下
那么,当你的业务符合上面3点,那么你可以考虑使用http连接池来提高服务器性能 使用http连接池的优点:
1.复用http连接,省去了tcp的3次握手和4次挥手的时间,极大降低请求响应的时间
2.自动管理tcp连接,不用人为地释放/创建连接
使用http连接池的大致流程 :
1.创建PoolingHttpClientConnectionManager实例
2.给manager设置参数
3.给manager设置重试策略
4.给manager设置连接管理策略
5.开启监控线程,及时关闭被服务器单向断开的连接
6.构建HttpClient实例
7.创建HttpPost/HttpGet实例,并设置参数
8.获取响应,做适当的处理
连接池结构图如下:

连接池管理器会为每个httpRoute单独的维护一个连接池。管理着available、leased、pending这些对象。同时,CPool本身也会维护一个总的available、leased、pending对象,是那些routeToPool中available、leased、pending的总和。这里介绍一下上图的几个概念
1. PoolEntity -连接池中的实体
包含ManagedHttpClientConnection连接;
连接的route路由信息;
以及连接存活时间相隔信息,如created(创建时间),updated(更新时间,释放连接回连接池时会更新),validUnit(用于初始化expiry过期时间,规则是如果timeToLive>0,则为created+timeToLive,否则为Long.MAX_VALUE),expiry(过期时间,人为规定的连接池可以保有连接的时间,除了初始化时等于validUnit,每次释放连接时也会更新,但是从newExpiry和validUnit取最小值)。timeToLive是在构造连接池时指定的连接存活时间,默认构造的timeToLive=-1。
ManagedHttpClientConnection是httpClient连接,真正建立连接后,其会bind绑定一个socket,用于传输HTTP报文。
2. LinkedList available – 存放可用连接 available 表示可用的连接,他们是用LinkedList来存放的。 当连接被使用完后,会被放入链表的头部。同时,当需要取连接时,也是从链表的头部开始遍历,直到获取可用的连接为止。这样做的目的是为了尽快的获取到可用的连接,因为在链表头部的都是刚放入链表的连接,离过期时间肯定是最远的。如果从链表尾部获取的话,那么很可能会获取到失效的连接。 同时,删除链表的失效连接时从链表尾部开始遍历的。
3. HashSet leased – 存放被租用的连接 leased存放正在被使用的连接。如果一个连接被创建或者从available 链表中取出,就会先放入leased集合中。同时,用完连接后,就从leased集合中移除掉掉。因为就add和remove操作,所以使用HashSet的数据结构,效率很高。 maxTotal的配置就是available链表和leased集合的总和限制。
4. LinkedList pending – 存放等待获取连接的线程的Future 当从池中获取连接时,如果available链表没有现成可用的连接,且当前路由或连接池已经达到了最大数量的限制,也不能创建连接了,此时不会阻塞整个连接池,而是将当前线程用于获取连接的Future放入pending链表的末尾,之后当前线程调用await(),释放持有的锁,并等待被唤醒。 当有连接被release()释放回连接池时,会从pending链表头获取future,并唤醒其线程继续获取连接,做到了先进先出。
5. RouteToPool
每个RouteToPool都会管理一个池,也就是持有pending 、leased 、available 这些对象。
同时,CPool本身也会维护一个总的available、leased、pending对象,是那些routeToPool中链表和集合的总和。
如果我们不给httpclient配置指定的连接管理器,在默认情况下,httpclient也会自动使用PoolingHttpClientConnectionManager作为连接管理器。
但是PoolingHttpClientConnectionManager默认的maxConnPerRoute和maxConnTotal分别是是2和20。也就是对于每个服务器最多只会维护2个连接,看起来有点少。所以,在日常使用时我们尽量使用自己配置的连接管理器比较好
后台线程清除过期和闲置过久的连接
如果每次获取连接时都要去判断连接是否过期或者关闭,会造成一定的性能损耗。另外如果连接长时间没用,长期闲置在那也是一种资源浪费。所以httpclient提供了一个机制,也就是开启后台线程定时的清除过期和闲置过久的连接。注意,4.5.2版本默认是有这个机制的,以前的版本不太确定有没有,如果没有我们也可以自己写一个。PoolingHttpClientConnectionManager提供了两个方法,closeExpiredConnections和closeIdleConnections,分别用来清除过期的连接以及闲置过久的连接。
这个线程默认是不开启的,我们可以在构建httpclient的时候设置
HttpClients.custom() .setDefaultRequestConfig(defaultRequestConfig)
//开启后台线程清除过期的连接
.evictExpiredConnections()
//开启后台线程清除闲置30秒以上的连接
.evictIdleConnections(30, TimeUnit.SECONDS)
.setConnectionManager(cm)
.setRetryHandler(httpRetryHandler).build();
https://blog.csdn.net/u013332124/article/details/82694076