Druid配置参数详解-minIdle
Druid是一个由阿里开源的数据库连接池,Druid的配置非常丰富,但是设置不当会对生产环境造成严重影响,网上Druid的资料虽多,但大部分都是互相复制粘贴,有很多不准确甚至完全错误的描述,Druid已经开源很久,而且作者WenShao的工作重心也已经不在Druid上,有些功能估计他自己都不太了解了。本系列将从源代码的角度分析Druid目前的最新版本(1.1.21)各个常用的配置项的具体含义以及是怎么起作用的。
画外音:目前Druid在开源中国举办的2019年度最受欢迎中国开源软件中排名第7名,支持Druid的朋友可以去投票哇。2019年度最受欢迎中国开源软件
minIdle是什么意思?
minIdle:连接池中的最小空闲连接数,Druid会定时扫描连接池的连接,如果空闲的连接数大于该值,则关闭多余的连接,反之则创建更多的连接以满足最小连接数要求。
为什么要设置这个参数?
设置这个参数可以应对突发流量,如果没有设置空闲连接,当有多个请求同时调用数据库,但是连接池中并没有可用连接,这时就必须创建连接,创建连接是一个非常耗时的操作,有可能会导致请求超时。
minIdle是怎么起作用的?
当连接池初始化时,会初始化一个定时清除空闲连接的任务DestroyTask,该任务默认是1分钟执行一次(使用timeBetweenEvictionRunsMillis参数设置)
protected void createAndStartDestroyThread() {
destroyTask = new DestroyTask();
if (destroyScheduler != null) {
long period = timeBetweenEvictionRunsMillis;
if (period <= 0) {
period = 1000;
}
//定时清除空闲连接的任务,默认1分钟执行一次
destroySchedulerFuture = destroyScheduler.scheduleAtFixedRate(destroyTask, period, period,
TimeUnit.MILLISECONDS);
initedLatch.countDown();
return;
}
String threadName = "Druid-ConnectionPool-Destroy-" + System.identityHashCode(this);
destroyConnectionThread = new DestroyConnectionThread(threadName);
destroyConnectionThread.start();
}
在这个定时任务中会判断连接池的连接是否满足关闭的条件,如果满足则关闭,满足的条件如下:
- 空闲时间大于minEvictableIdleTimeMillis(默认30分钟),并且空闲连接数大于minIdle;
- 空闲时间大于maxEvictableIdleTimeMillis(默认7小时);
//关闭条件,空闲时间大于minEvictableIdleTimeMillis,并且空闲连接大于minIdle,
// 其中checkCount为poolingCount - minIdle,即可能被关闭的连接数量
//或者空闲时间大于maxEvictableIdleTimeMillis
if (idleMillis >= minEvictableIdleTimeMillis) {
if (checkTime && i < checkCount) {
evictConnections[evictCount++] = connection;
continue;
} else if (idleMillis > maxEvictableIdleTimeMillis) {
evictConnections[evictCount++] = connection;
continue;
}
}
当然也有可能这时数据库中的连接数小于minIdle这个时候就需要创建新的连接了
if (keepAlive && poolingCount + activeCount < minIdle) {
needFill = true;
}
if (needFill) {
lock.lock();
try {
int fillCount = minIdle - (activeCount + poolingCount + createTaskCount);
for (int i = 0; i < fillCount; ++i) {
//通知CreateConnectionTask创建连接
emptySignal();
}
} finally {
lock.unlock();
}
总结
- minIdle的意义是预防突发流量;
- 数据源会在DestroyTask定时检查池中的空闲连接,会关闭多余的连接或者创建新的连接。
- 数据源并不能确保空闲连接一定等于minIdle,可以通过设置timeBetweenEvictionRunsMillis参数调整定时任务的执行间隔,从而控制数据源中空闲连接数更加接近minIdle;