③拿到一个连接
//③
//获取连接的时候, 判断连接是否已经被标记移除
if (poolEntry.isMarkedEvicted() || (clockSource.elapsedMillis(poolEntry.lastAccessed, now) > ALIVE_BYPASS_WINDOW_MS && !isConnectionAlive(poolEntry.connection))) {
//如果连接超出maxLifetime, 或者连接测试不通过, 就关闭连接
closeConnection(poolEntry, "(connection is evicted or dead)"); // Throw away the dead connection (passed max age or failed alive test)
//剩余超时时间
timeout = hardTimeout - clockSource.elapsedMillis(startTime);
}
复制代码
如果connectionBag给我们返回了一个连接,那么需要判断两个条件:
该连接是否被软驱逐了,poolEntry.isMarkedEvicted()
该连接是否已经不可用了或者说已经不能通过连接检查,!isConnectionAlive(poolEntry.connection)
为什么需要判断呢?连接池里的连接不应该都是可用的状态吗?
这里涉及到 HikariCP 的一个设计点,HikariCP 的连接不是实时从连接池里剔除的,只是给连接上打个标记而已,都是在获取连接的时候检查是否可用,如果不可用的时候才直接从连接池里删除。如果在 HikariCP 的任何地方都可能剔除连接,那么剔除连接的地方会比较多,会很乱,也容易引发 bug。反之,把剔除链接的操作收缩到某几个固定的逻辑中,就比较好管理。
软驱逐
我们在上面提到一个软驱逐的地方, 就是挂起连接池修改配置的时候,修改完之后要软驱逐所以的连接,使新配置生效。
其实软驱逐是一个标记状态,是一个软删除,在PoolEntry上,有个状态叫做evict,如果是 true,那么,该连接已经被标记删除,不能使用了。然后某个线程在获取连接的时候,正好拿到了这个连接,判断出来它已经被软驱逐,就触发从连接池删除该连接的逻辑。
关闭连接的逻辑我们后面单独分析,此处就不深入了。
连接可用检查
检查连接是否可用的条件,其实是两个:(clockSource.elapsed

文章详细分析了HikariCP连接池在获取连接时的检查过程,包括软驱逐、连接可用性检查以及连接的代理和泄露检测机制。在获取连接时,会判断连接是否被标记为不可用或超时,并在必要时关闭连接。此外,HikariCP使用代理连接来防止用户误操作导致的连接问题,并提供了泄露检测功能以确保资源的有效管理。
最低0.47元/天 解锁文章
4182





