hiricacp 连接池校验机制

devtools/2024/10/15 22:14:44/

一、背景

项目发生告警,但是并没有影响业务,看了下日志,红框里面有循环调用了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. 释放锁:确保锁被释放,即使在异常情况下

http://www.ppmy.cn/devtools/126373.html

相关文章

laravel DCAT 中如何修改面包屑导航栏内容

dcat中修改面包屑 一、背景二、找到设置的方法三、修改面包屑 一、背景 DCAT的页面还是非常干净的,当设置语言格式为zh_CN以后,发现面包屑导航还有英文,如下图所示: 二、找到设置的方法 根据dcat文档介绍,页面分为…

美团Java一面

美团Java一面 9.24一面,已经寄了 收到的第一个面试,表现很不好 spring bean生命周期 作用域(忘完了) 为什么用redis缓存 redis和数据库的缓存一致性问题 redis集群下缓存更新不一致问题 aop说一下 arraylist和linkedlist 数据库的…

Qt初识_项目文件解析

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Qt初识_项目文件解析 收录于专栏【Qt开发】 本专栏旨在分享学习Qt的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. pro文件解析 2.…

Ruby XML, XSLT 和 XPath 教程

Ruby XML, XSLT 和 XPath 教程 1. 引言 Ruby 是一种动态、开放源代码的编程语言,广泛用于网页开发、数据分析和各种自动化任务。在处理 XML(可扩展标记语言)时,Ruby 提供了强大的库和工具,使得解析、转换和提取 XML …

【IC验证】随机约束

1.约束 (1)注意 一般随机约束只能在类中使用; (2)实现步骤 在定义变量时,用rand/randc关键字进行修饰; 定义约束; 创建并实例化类后,调用随机约束方法; &am…

浅谈C++之日志记录

在 C 中使用 log4net 进行日志记录,您需要遵循以下步骤: 安装 log4net: 首先,您需要在您的 .NET 项目中包含 log4net 库。通常,这可以通过 NuGet 包管理器来完成。 配置 log4net: 您需要创建一个配置文件…

发布-订阅模式(Publisher-Subscriber)

实际上,发布-订阅模式只是观察者模式的一个别称。 但是经过时间的沉淀,似乎他已经强大了起来,已经独立于观察者模式,成为另外一种不同的设计模式。在现在的发布订阅模式中,称为发布者的消息发送者不会将消息直接发送给…

python对weedfs的操作

1、weedfs的简介 如果你对weed储存有一定的理解也可以忽略 WeedFS(Weed File System)是一个开源的分布式文件系统,由Go语言编写,旨在解决海量文件存储和访问的问题。它采用了类似于Hadoop HDFS的分布式文件系统架构,…