欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > hiricacp 连接池校验机制

hiricacp 连接池校验机制

2025/2/23 19:55:17 来源:https://blog.csdn.net/soldier_jw/article/details/142139880  浏览:    关键词:hiricacp 连接池校验机制

一、背景

项目发生告警,但是并没有影响业务,看了下日志,红框里面有循环调用了3次 ,一直以为是外部的重试在重试,但是外部确没有重试记录,就深扒了代码

 二、想法

我知道hikaricp获取连接之后会校验连接的有效性,就猜想如果校验失败了,那本次请求是不是就是失败了,如果这样的话,那就没校验的意义了,所以肯定有重试机制用以保证请求的完整性。

三、实践

HikariDataSource.class

@Overridepublic Connection getConnection() throws SQLException{if (isClosed()) {throw new SQLException("HikariDataSource " + this + " has been closed.");}if (fastPathPool != null) {return fastPathPool.getConnection();}// See http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_JavaHikariPool result = pool;if (result == null) {synchronized (this) {result = pool;if (result == null) {validate();LOGGER.info("{} - Starting...", getPoolName());try {pool = result = new HikariPool(this);this.seal();}catch (PoolInitializationException pie) {if (pie.getCause() instanceof SQLException) {throw (SQLException) pie.getCause();}else {throw pie;}}LOGGER.info("{} - Start completed.", getPoolName());}}}return result.getConnection();}
这里面调用了   result.getConnection();  result为hikariPool
HikariPool.class
public Connection getConnection() throws SQLException
{return getConnection(connectionTimeout);
}public Connection getConnection(final long hardTimeout) throws SQLException{suspendResumeLock.acquire();final long startTime = currentTime();try {long timeout = hardTimeout;do {PoolEntry poolEntry = connectionBag.borrow(timeout, MILLISECONDS);if (poolEntry == null) {break; // We timed out... break and throw exception}final long now = currentTime();if (poolEntry.isMarkedEvicted() || (elapsedMillis(poolEntry.lastAccessed, now) > aliveBypassWindowMs && !isConnectionAlive(poolEntry.connection))) {closeConnection(poolEntry, poolEntry.isMarkedEvicted() ? EVICTED_CONNECTION_MESSAGE : DEAD_CONNECTION_MESSAGE);// elapsedMillis 方法是将当前时间戳-startTime 得出的时间差timeout = hardTimeout - elapsedMillis(startTime);}else {metricsTracker.recordBorrowStats(poolEntry, startTime);return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry), now);}} while (timeout > 0L);metricsTracker.recordBorrowTimeoutStats(startTime);throw createTimeoutException(startTime);}catch (InterruptedException e) {Thread.currentThread().interrupt();throw new SQLException(poolName + " - Interrupted during connection acquisition", e);}finally {suspendResumeLock.release();}}

方法整体流程

  1. 获取锁:确保线程安全。
  2. 记录开始时间:用于后续计算超时和统计。
  3. 尝试获取连接
    • 在给定的超时时间内循环尝试获取连接。   

      elapsedMillis 方法是将当前时间戳-startTime 得出的时间差

    • 如连接无效则关闭连接并继续尝试。
    • 如连接有效则记录统计信息并返回连接。
  4. 超时处理:如在规定时间内未能成功获取连接,记录超时统计信息并抛出 SQLException
  5. 异常处理:捕获 InterruptedException 并抛出相应的 SQLException
  6. 释放锁:确保锁被释放,即使在异常情况下

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词