buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

apache commons-pool2中GenericObjectPoolConfig的maxTotal、maxIdle、minIdle属性理解

Apache commons-pool本质上是"对象池",即通过一定的规则来维护对象集合的容器。commos-pool在很多场景中,用来实现"连接池"/"任务worker池"等。大家常用的dbcp数据库连接池、jedis连接池,也都是基于commons-pool实现。

 

关于对象池,commons-pool2中有如下类关系(Cloneable在rt.jar里)

其中,GenericObjectPoolConfig是在GenericObjectPool构造的时候使用的,用来设置pool的maxTotal、maxIdle、minIdle等属性。

我们熟知的JedisPool,即是利用了commons-pool2来实现的。在jedis中 JedisPoolConfig 继承自 GenericObjectPoolConfig 。JedisPool称为资源池、连接资源池,简称连接池,参见JedisPool#getResource。

package redis.clients.jedis;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class JedisPoolConfig extends GenericObjectPoolConfig {
  public JedisPoolConfig() {
    // defaults to make your life with connection pool easier :)
    setTestWhileIdle(true);
    setMinEvictableIdleTimeMillis(60000);
    setTimeBetweenEvictionRunsMillis(30000);
    setNumTestsPerEvictionRun(-1);
  }
}
View Code

 

关于minIdle、maxIdle、maxTotal这三个属性

minIdle:对象池中最小空闲的对象个数,默认为0。new一个对象池时,会初始创建minIdle个对象(实际上并没有,而是在需要的时候才开始创建,我们的java线程池就是这么做的)。当开启了回收机制后,如果对象空闲时间达到了设定值,则会被销毁、移出对象池。但对象池中至少会保留minIdle个对象。
maxIdle:对象池中最大空闲的对象个数。在归还对象时,对象会处于idle状态,这时,对象池会判断idle对象个数,如果已经达到maxIdle,则对象会被直接销毁,否则才会放回对象池(此时,对象池的活跃对象个数+1)。
maxTotal:对象池中允许的最大对象个数。在从对象池获取对象时,如果对象池中有idle对象,则直接返回一个对象。否则,判断活跃对象是否已经达到maxTotal,是的话说明所有对象都在干活,这时就会发生阻塞等待,直到有对象归还对象池;没有达到maxTotal,则就会创建一个新对象供使用。(获取对象的结果是:对象池的活跃对象个数-1)

 

对象池中,对象生命周期

 

 

阻塞获取对象时的超时参数

    • maxWaitMillis
      当连接池资源耗尽时,获取可用对象所需的等待时间,超出则抛异常,默认为-1即永不超时
    • blockWhenExhausted
      当这个值为true的时候,maxWaitMillis参数才能生效。为false的时候,当连接池没资源,则立马抛异常。默认为true

 

对象池对象移除策略

常见的移除策略有:

1. LRU(Least Recently Used): 淘汰最长时间未被使用的 
2. LFU(least frequently used)淘汰一定时期内被访问次数最少的

 

ref:

Apache commons-pool对象池原理分析

GenericObjectPool参数解析

posted on 2022-12-12 20:05  buguge  阅读(1344)  评论(0编辑  收藏  举报