Java

Hikari连接的创建过程

2021-04-22  本文已影响0人  holysu

HouseKeeper 和 HikariPool#addBagItem 在需要新增db连接的时候,都是往负责连接创建的线程池 addConnectionExecutorPoolEntryCreator implements Callable<Boolean> 任务

PoolEntryCreator#call()

public Boolean call(){
    long sleepBackoff = 250L;
        **// 1.** 判断是否需要创建
    while (poolState == POOL_NORMAL && **shouldCreateAnotherConnection()**) {
      **// 2.** 创建db连接条目
      final PoolEntry poolEntry = createPoolEntry();
      if (poolEntry != null) {
         connectionBag.add(poolEntry);
         logger.debug("{} - Added connection {}", poolName, poolEntry.connection);
         if (loggingPrefix != null) {
            logPoolState(loggingPrefix);
         }
         return Boolean.TRUE;
      }
            
            **// 3.** 休眠后重试
      // failed to get connection from db, sleep and retry
      if (loggingPrefix != null) logger.debug("{} - Connection add failed, sleeping with backoff: {}ms", poolName, sleepBackoff);
      quietlySleep(sleepBackoff);
      sleepBackoff = Math.min(SECONDS.toMillis(10), Math.min(connectionTimeout, (long) (sleepBackoff * 1.5)));
   }

   // Pool is suspended or shutdown or at max size
    return Boolean.FALSE;
}

1. while (poolState == POOL_NORMAL && shouldCreateAnotherConnection()) { .. } 判断是否需要创建

private synchronized boolean shouldCreateAnotherConnection() {
         return getTotalConnections() < config.getMaximumPoolSize() &&
            (connectionBag.getWaitingThreadCount() > 0 || getIdleConnections() < config.getMinimumIdle());
}

当前总的连接数小于 maximumPoolSize 最大连接数的前提下,如果有线程等待 db连接 或 池内空闲线程数小于最小空闲线程数 才会去创建新db连接

2. final PoolEntry poolEntry = createPoolEntry(); 创建db连接条目,成功的话添加到池子 connectionBag 里

private PoolEntry createPoolEntry()
   {
      try {
         final PoolEntry poolEntry = newPoolEntry();

         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(new MaxLifetimeTask(poolEntry), lifetime, MILLISECONDS));
         }

         final long keepaliveTime = config.getKeepaliveTime();
         if (keepaliveTime > 0) {
            // variance up to 10% of the heartbeat time
            final long variance = ThreadLocalRandom.current().nextLong(keepaliveTime / 10);
            final long heartbeatTime = keepaliveTime - variance;
            poolEntry.setKeepalive(houseKeepingExecutorService.scheduleWithFixedDelay(new KeepaliveTask(poolEntry), heartbeatTime, heartbeatTime, MILLISECONDS));
         }

         return poolEntry;
      }
    //...
    return null;
}

maxLifetime 连接创建后的最大存活时间,超过后就会被清除
keepaliveTime 则是多久检查一次连接的活性,必须比 maxLifetime小 , 在申请到的连接空闲超过一定时间的话,在使用前也会记性 alive 活性判断,一般keepaliveTime 也没大必要

3. 如果db连接创建失败,则休眠 250ms 后,再进入while逻辑,重新尝试

上一篇 下一篇

猜你喜欢

热点阅读