当我们使用JedisPool 创建redis的连接对象时,通常会传入GenericObjectPoolConfig对象。这个对象实际上是rg.apache.commons.pool2.impl apache提供的对象池工具包里的配置,实际上这也可以说明jedis的连接池是依托于apache提供的对象池的方式来创建连接对象。今天我主要说一下GenericObjectPoolConfig中的minIdle属性。

关于minIdle

minIdle在对象池里比较常见的属性,但是在apache提供的对象池里,它最主要的作用是设置要在池中维护的最小空闲对象数的目标。这个设置仅在它为正且getTimeBetweenEvictionRunsMillis()大于零时才有效。如果满足这种情况,则会尝试确保池在空闲对象驱逐运行期间具有所需的最小实例数。

我们可以看一下对应的构造函数:

public GenericObjectPool(PooledObjectFactory<T> factory,
            GenericObjectPoolConfig config) {

        super(config, ONAME_BASE, config.getJmxNamePrefix());

        if (factory == null) {
            jmxUnregister(); // tidy up
            throw new IllegalArgumentException("factory may not be null");
        }
        this.factory = factory;

        idleObjects = new LinkedBlockingDeque<PooledObject<T>>(config.getFairness());

        setConfig(config);
		//1.启动一个定时驱逐任务 	
        startEvictor(getTimeBetweenEvictionRunsMillis());
    }


    final void startEvictor(long delay) {
        synchronized (evictionLock) {
            if (null != evictor) {
                EvictionTimer.cancel(evictor);
                evictor = null;
                evictionIterator = null;
            }
            if (delay > 0) {
                evictor = new Evictor();
                EvictionTimer.schedule(evictor, delay, delay);
            }
        }
    }

​ 在这里会启动一个定时驱逐任务来确保最小的空闲实例,getTimeBetweenEvictionRunsMillis()这个方法返回正数才执行。这个任务需要注意以下几点:

  1. 任务里会执行两步操作,evict()ensureMinIdle() ,其中ensureMinIdle()方法会检查当前的池中的对象个数是否小于minIdle的配置,如果小于的话则会创建:
  if (idleCount < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) {
            return;
        }

        while (idleObjects.size() < idleCount) {
            PooledObject<T> p = create();
        // .....
    }

因此我们可以通过timeBetweenEvictionRunsMillis与minIdle来控制驱逐任务的执行

  1. 默认情况下,非Error错误会吞噬异常信息。如果刚开始redis连接不上那么很可能在创建时就不能及时看到错误信息,不过我们可以实现org.apache.commons.pool2.SwallowedExceptionListener接口来监听并处理对应的异常信息
posted on 2022-02-16 19:23  聂晨  阅读(476)  评论(0编辑  收藏  举报