Hikari关闭连接的时机

  • houseKeeper 定时检查空闲连接,对于超过 minimumIdle 的那部分db连接,如果空闲时长大于 idleTimeout 则关闭 softEvictConnection()
  • db连接从创建后超过最大存活时长 maxLifeTime 的时候 softEvictConnection() 驱除连接
  • 每隔 keepaliveTime 检查连接的有效性,如果db连接不可用,则直接关闭 closeConnection
  • HikariPool#getConnection() 申请到的连接超过500ms未使用,检查连接可用性失败的时候 reserse() + closeConnection()
  • 程序显式调用 HikariDataSource#evictConnection HikariPool#evict Connection
  • 数据源 HikariDataSource#close() 关闭,HikariPool#shutdown() 关闭所有连接

hikari 关闭连接的前提是,连接当前处于空闲(STATE_IN_USE) 或者 被保留( STATE_RESERVED) 状态

HikariPool#closeConnection 直接关闭连接的逻辑

void closeConnection(final PoolEntry poolEntry, final String closureReason)
  {
			//从池子中移除,前提是poolEntry状态为 STATE_IN_USE或 STATE_RESERVED,并把状态变为 MOVED
      if (connectionBag.remove(poolEntry)) {
				 // 获取物理连接,交给负责关闭db连接的线程池关闭
         final Connection connection = poolEntry.close();
         closeConnectionExecutor.execute(() -> {
            quietlyCloseConnection(connection, closureReason);
						//触发一下填充连接的逻辑
            if (poolState == POOL_NORMAL) {
               fillPool();
            }
         });
      }
  }

houseKeeper 和 maxLifetime 这类检测任务要关闭线程的时候,需要确保db连接空闲才行,调用的是 softEvictConnection 软驱除的方法

private boolean softEvictConnection(final PoolEntry poolEntry, final String reason, final boolean owner)
{
   **poolEntry.markEvicted();**
   if (owner || connectionBag.reserve(poolEntry)) {
      closeConnection(poolEntry, reason);
      return true;
   }
 
   return false;
}

先把连接标记为 evict,如果连接此刻处于空闲状态 connectionBag.reserve(poolEntry) 才能执行成功将其状态变为 RESERVED 状态,进而 直接 closeConnection ;否则要等别的线程申请db连接时,再把 evict=true 的连接给关闭掉

  • hikari 关闭连接的前提是,连接当前处于空闲(STATE_IN_USE) 或者 被保留( STATE_RESERVED) 状态
  • 物理连接关闭后,会调用一下 fillPool(); 维护连接池数量
posted @ 2021-04-16 00:51  mushishi  阅读(1705)  评论(0编辑  收藏  举报