httpclient 设置超时时间_HttpClient连接池指标分析

本文介绍了HttpClient连接池的使用,重点关注设置超时时间、监控连接池指标,包括最大连接数、路由最大连接数、正在使用、可用和等待连接的线程数。讨论了获取和释放连接的流程,并提出通过Pinpoint进行连接池监控的方法。
摘要由CSDN通过智能技术生成

HttpClient在我们项目中普遍使用,同时我们也会使用它的连接池来复用连接,减少了每次连接建立的过程。HttpClient的连接池是在4.3之后的版本才有,我们可以通过PoolingHttpClientConnectionManager来管理我们的连接池以及查看连接池的使用情况。那么连接池主要有哪些指标呢?

maxTotal:单个连接池实例能允许的最大连接数,当然如果你使用了多个连接池实例,也就有多个maxTotal指标

defaultMaxPerRoute:每个路由(Route)的最大数

我们在使用HttpClient的连接池时,主要会设置最大连接数maxTotal,以及单个路由的最大连接数defaultMaxPerRoute,当然也可以针对特定的路由去单独配置最大的连接数。这里的路由怎么理解呢?可以简单的理解为目标host,比如我请求了www.baidu.comwww.sina.com,那么这里就有两个路由

除了上述两个最常使用的指标,还有下面一些指标值得我们关注

leased:连接池中正在使用的连接数

available:连接池中可用的连接数,这里的是连接被使用完后可被复用

pending:等待获取连接的线程数

在HttpClient中,连接池由CPool表示,该类继承AbstractConnPool ,此类的一些成员变量如下:

d490c33cee968bc9e7a66ec92fb78b2b.png

其中,leased保存的是正在被使用的连接集合,其size便是这个连接池的正在使用的连接数大小,available保存的是可用的连接(这些连接是已经和目标host建立过连接的),pending保存的是正在等待获取连接的线程,这三个值是从连接池纬度总体的指标,不同的路由对应的指标信息保存在routeToPool,其中key为Route,value为RouteSpecificPoolRouteSpecificPool如下:

d9259ddec8c8ae33ea26c3481179af44.png

可以看到单个路由下也有leased、available、pending三个指标,所有路由的指标值的和等于总的连接池的指标值

获取连接

从连接池里获取连接的核心方法是:org.apache.http.pool.AbstractConnPool#getPoolEntryBlocking

  1. 对连接池加锁
  2. 根据routerouteToPool中获取对应route的连接池,如果没有则创建一个,并添加到routeToPool
  3. 从第2步中获取的route对应的连接池中循环获取获取可用的连接
    1. 如果available列表不为空(说明有可用的),则从前往后遍历,如果有则将该连接从route下的available中移除,加到route的leased中(表明被使用),返回该连接;如果available列表为空,返回null
    2. 如果获取到了连接则需要判断连接是否过期,如果过期了,则需要从此route下移除该连接,同时还需要在总的连接池的available列表中移除该连接
  4. 经过第3个步骤如果拿到了连接,则说明获取到了一个之前存在的可复用的连接,从总的连接池的available列表中移除该连接并加入到总的连接池的leased
  5. 如果第3个步骤没有拿到连接,则说明新建立连接
    1. 获取该route允许的最大连接数
    2. 判断此route已分配(available+leased)的连接数是否超过该route的最大连接数
      1. 如果超过,那么将available从后往前关闭连接并从总的连接池的available移除,同时从此route的连接池中移除
    3. 如果经过2步骤后发现已分配的连接数还是大于route的最大连接数说明连接超过上限,该请求需要等待,因此加此route下的连接池的pending中,同时也会加入总的连接池的pending中,并等待设置的超时时间
    4. 如果经过2步骤发现已分配的连接数小于路由最大连接数,说明可以分配连接,这时还需要在总的数量上做判断
      1. 判断总的连接池数量有没有超过连接池的maxTotal
      2. 如果超过了还是需要等待,即进入5.3步骤
      3. 如果没有超过
        1. 如果总的连接数都是在available中(即available+leased=maxTotal的情况),则需要先从available中移除一个连接(可能是别的route下的连接)
        2. 创建连接,并加入到该route下的连接池的leased和总的连接池的leased中
  6. 释放锁

释放连接

连接释放位于org.apache.http.pool.AbstractConnPool#release

其中有一个参数reusable来判断此连接是否复用

  1. 连接池加锁
  2. 从连接池的leased中移除此连接
  3. 根据连接的route获取此route的连接池
    1. route的连接池的available中移除此连接
    2. 如果连接可复用,即reusabletrue,则加入到route的连接池的available
  4. 如果连接可复用,即reusabletrue,则加入到总的连接池的available
  5. route下的连接池的pending中获取并移除一个等待连接的任务
    1. 如果存在那么从总的连接池的pending中移除此任务
    2. 如果不存在,那么从总的连接池的pending中获取并移除一个任务
  6. 唤醒获取的这个任务
  7. 释放锁

参数reusable是通过连接可重用策略决定,默认实现是org.apache.http.impl.DefaultConnectionReuseStrategy

如何监控

因为连接池也是比较重要的资源,那么如何去监控连接池的使用情况呢?目前因为我们接入了pinpoint,参照其监控数据库资源的套路对httpclient连接池进行监控,注意通过PoolingHttpClientConnectionManager获取连接池指标时,因为都加锁了,所以注意获取指标的频率别过高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值