当我们使用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()
这个方法返回正数才执行。这个任务需要注意以下几点:
- 任务里会执行两步操作,
evict()
与ensureMinIdle()
,其中ensureMinIdle()方法会检查当前的池中的对象个数是否小于minIdle的配置,如果小于的话则会创建:
if (idleCount < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) {
return;
}
while (idleObjects.size() < idleCount) {
PooledObject<T> p = create();
// .....
}
因此我们可以通过timeBetweenEvictionRunsMillis与minIdle来控制驱逐任务的执行
- 默认情况下,非
Error
错误会吞噬异常信息。如果刚开始redis连接不上那么很可能在创建时就不能及时看到错误信息,不过我们可以实现org.apache.commons.pool2.SwallowedExceptionListener
接口来监听并处理对应的异常信息