druid的maxEvictableIdleTimeMillis 和 hikariCP 的 maxLifetime


先看看 Druid 的 maxEvictableIdleTimeMillis 是啥?

DestroyTask 線程銷毀任務每隔 timeBetweenEvictionRunsMillis (默認一分鍾)的時間會執行一次連接池瘦身檢測 DruidDataSource#shrink(checkTime:true, keepAlive);

if (idleMillis >= minEvictableIdleTimeMillis) {
    if (checkTime && i < checkCount) {  // checkCount = poolingCount - minIdle
        evictConnections[evictCount++] = connection;
        continue;
    } else if (idleMillis > maxEvictableIdleTimeMillis) {
        evictConnections[evictCount++] = connection;
        continue;
    }
}

checkTime = true 所以會再判斷 i < checkCount 是否成立,而 checkCount = poolingCount - minIdle 也就是超過 minIdle 那部分連接(類似線程池的 maximumPoolSize - corePoolSize )

所以,代碼邏輯是 1~minIdle 的連接空閑超過 maxEvictableIdleTimeMillis(默認7小時) 則需要清除掉, minEvictableIdleTimeMillis(默認30分鍾) 針對的是超過 minIdle 的那部分連接

maxEvictableIdleTimeMillis 表示的是 minIdle 內連接能空閑的最大時長

hikariCP 的 maxLifetime

HikariPool#createPoolEntry 創建連接池條目

final long maxLifetime = config.getMaxLifetime();
if (maxLifetime > 0) {
   // variance up to 2.5% of the maxlifetime
   final long variance = maxLifetime > 10_000 ? ThreadLocalRandom.current().nextLong( maxLifetime / 40 ) : 0;
   final long lifetime = maxLifetime - variance;
   poolEntry.setFutureEol(houseKeepingExecutorService.schedule(
      () -> {
         if (softEvictConnection(poolEntry, "(connection has passed maxLifetime)", false /* not owner */)) {
            addBagItem(connectionBag.getWaitingThreadCount());
         }
      },
      lifetime, MILLISECONDS));
}

hikari在創建連接后,如果maxLifetime 大於0 ,則會起一個定時任務,在 maxLifetime(做了點時間隨機) 之后會移除這個連接;不管這個連接是否最近還在用, 非常硬氣;也就是說

maxLifetime 表示的是連接在創建后最大能存活時間,與最近活躍/空閑與否無關

但是在高並發服務里(ygc 頻繁) maxLifetime 可能會導致被驅除的連接每隔7小時由於超齡進入到老年代, 如果連接池設置較大 可能會導致fullgc stw過久 (cms 的 final remak階段 )

為什么它們默認都是7小時?

時下比較常用的 mysql 數據庫默認的配置,如果物理連接空閑超過8小時會自動關閉

所以為了保證 minIdle\minimumIdle 這些常駐在連接池的連接的活性,防止它們空閑過久,被數據庫那邊關了,特別是像晚上低峰期12點到早高峰8點剛好超過8小時后,剛進入業務高峰期拿到的連接都是不可用的, 定時檢查,提前重建

檢查連接可用性的其他參數

druid 檢查連接活性的其他參數還有 testOnBorrow、testOnReturn、testWhileIdle

  • testOnBorrow 和 testOnReturn 分別是申請連接和歸還連接的時候去 執行下 validationQuery 校驗,對性能有影響 一般是關閉的
  • testWhileIdle 在申請連接的時候,如果連接空閑超過 timeBetweenEvictionRunsMillis 則 validationQuery 校驗;對性能沒什么影響

hikariCP 沒有暴露類似的參數,但是每次申請到連接的時候 都去檢查連接是否超過500ms,如果是則檢查連接的可用性

testWhileIdle 這種機制不能取代 maxEvictableIdleTimeMillis 和 maxLifetime ,因為它是在申請連接的時候才做判斷,比較被動;

和dba確認,數據庫服務配置的連接空閑超時時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM