Druid配置參數詳解-testWhileIdle
Druid是一個由阿里開源的數據庫連接池,Druid的配置非常豐富,但是設置不當會對生產環(huán)境造成嚴重影響,網上Druid的資料雖多,但大部分都是互相復制粘貼,有很多不準確甚至完全錯誤的描述,Druid已經開源很久,而且作者WenShao的工作重心也已經不在Druid上,有些功能估計他自己都不太了解了。本系列將從源代碼的角度分析Druid目前的最新版本(1.1.21)各個常用的配置項的具體含義以及是怎么起作用的。
畫外音:目前Druid在開源中國舉辦的2019年度最受歡迎中國開源軟件中排名第7名,支持Druid的朋友可以去投票哇。2019年度最受歡迎中國開源軟件
testWhileIdle是什么意思?
testWhileIdle:如果為true(默認true),當應用向連接池申請連接,并且testOnBorrow為false時,連接池將會判斷連接是否處于空閑狀態(tài),如果是,則驗證這條連接是否可用。
testWhileIdle什么時候會起作用?
- 獲取連接時;
- testOnBorrow==false;
- testWhileIdle==true;
使用代碼在DruidDataSource的getConnectionDirect方法
注意:此時判斷連接空閑的依據是空閑時間大于timeBetweenEvictionRunsMillis(默認1分鐘),并不是使用minEvictableIdleTimeMillis跟maxEvictableIdleTimeMillis,也就是說如果連接空閑時間超過一分鐘就測試一下連接的有效性,但并不是直接剔除;而如果空閑時間超過了minEvictableIdleTimeMillis則會直接剔除。
if (testOnBorrow) {
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
discardConnection(poolableConnection.holder);
continue;
}
} else {
if (poolableConnection.conn.isClosed()) {
discardConnection(poolableConnection.holder); // 傳入null,避免重復關閉
continue;
}
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;
if (timeBetweenEvictionRunsMillis <= 0) {
timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
}
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;
}
}
}
}
連接池是如何判斷連接是否有效的?
判斷連接是否可用同testOnBorrow
Druid配置參數詳解-testOnBorrow
總結
testWhileIdle的作用跟testOnBorrow是差不多的,都是在獲取連接的時候測試連接的有效性,如果兩者都為true,則testOnBorrow優(yōu)先級高,則不會使用到testWhileIdle。