DruidDataSource参数解析
testOnBorrow
当testOnBorrow
为true
时,每次获取连接都会进行连接校验,当连接不可用,则关闭连接。不推荐使用
if (testOnBorrow) {
//测试连接
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
//连接不可用,则关闭连接
discardConnection(poolableConnection.holder);
continue;
}
}
testOnReturn
当testOnReturn
为true
时,每次回收连接都会进行一次连接校验。不推荐使用
if (testOnReturn) {
//测试连接
boolean validate = testConnectionInternal(holder, physicalConnection);
if (!validate) {
//关闭连接
JdbcUtils.close(physicalConnection);
//销毁连接计数+1
destroyCountUpdater.incrementAndGet(this);
//获取锁
lock.lock();
try {
if (holder.active) {
//存活连接计数减一
activeCount--;
//连接设置未存活
holder.active = false;
}
//关闭连接计数+1
closeCount++;
} finally {
//释放锁
lock.unlock();
}
return;
}
}
testWhileIdle
当testWhileIdle
为true
时,并且testOnBorrow
为false
,会去计算连接的最后活跃时间(lastActiveTimeMillis
)和当前时间的间隔(idleMillis
)。
时间间隔再和校验时间(timeBetweenEvictionRunsMillis
)做比较,一旦连接的间隔大于校验时间,则开始校验这个连接是否可用。
防止因为TCP被迫断开连接的关系,导致的连接不可用。非常推荐开启使用
if (testWhileIdle) {
final DruidConnectionHolder holder = poolableConnection.holder;
//当前时间
long currentTimeMillis = System.currentTimeMillis();
//连接最后活跃的时间
long lastActiveTimeMillis = holder.lastActiveTimeMillis;
//连接最后执行的时间
long lastExecTimeMillis = holder.lastExecTimeMillis;
//连接最后保持的时间
long lastKeepTimeMillis = holder.lastKeepTimeMillis;
//如果开启检查,并且最后执行时间不等于最后活跃时间,则最后活跃时间等于最后执行时间
if (checkExecuteTime
&& lastExecTimeMillis != lastActiveTimeMillis) {
lastActiveTimeMillis = lastExecTimeMillis;
}
//如果最后保持连接的时间大于最后活跃时间,则最后活跃时间等于最后保持时间
if (lastKeepTimeMillis > lastActiveTimeMillis) {
lastActiveTimeMillis = lastKeepTimeMillis;
}
//计算空闲时间间隔
long idleMillis = currentTimeMillis - lastActiveTimeMillis;
//超时的间隔
long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
//如果时间间隔未设置,则默认为60秒
if (timeBetweenEvictionRunsMillis <= 0) {
timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
}
//如果空闲时间大于超时时间,或者空闲时间小于0(也就是最后活跃时间大于当前时间)
if (idleMillis >= timeBetweenEvictionRunsMillis
|| idleMillis < 0 // unexcepted branch
) {
//开始校验连接
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
//连接无法使用,则关闭连接
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
discardConnection(poolableConnection.holder);
continue;
}
}
}
phyConnectTimeMillis
phyConnectTimeMillis
连接时长超时销毁时间,一旦设置后,当前连接保持的时长,大于该值,则直接关闭连接。
回收方法(recycle
)的使用
if (phyTimeoutMillis > 0) {
long phyConnectTimeMillis = currentTimeMillis - holder.connectTimeMillis;
if (phyConnectTimeMillis > phyTimeoutMillis) {
//销毁连接
discardConnection(holder);
return;
}
}
if (phyTimeoutMillis > 0) {
long phyConnectTimeMillis = currentTimeMillis - connection.connectTimeMillis;
if (phyConnectTimeMillis > phyTimeoutMillis) {
//将连接放入到销毁池中
evictConnections[evictCount++] = connection;
continue;
}
}
检查并收缩连接方法(shrink
)的使用
phyMaxUseCount
phyMaxUseCount
连接的最大使用次数,该参数被设置后,在回收方法(recycle
)中,会判断连接是否达到最大使用次数,达到则直接回收。
//如果连接最大使用次数大于0,并且连接也达到了使用次数,则直接关闭
if (phyMaxUseCount > 0 && holder.useCount >= phyMaxUseCount) {
//销毁连接
discardConnection(holder);
return;
}