当前位置:网站首页>五、HikariCP源码分析之初始化分析二
五、HikariCP源码分析之初始化分析二
2022-06-25 19:08:00 【用户1422411】
欢迎访问我的博客,同步更新: 枫山别院
源代码版本2.4.5-SNAPSHOT
HikariPool的初始化
在上一节,我们说到了pool = fastPathPool = new HikariPool(this);中的new HikariPool(this)。我们来看下代码:
public HikariPool(final HikariConfig config) {
//①
//PoolBase
super(config);
//②
// 构建一个connectionBag用于保存连接, connectionBag是连接池的核心
this.connectionBag = new ConcurrentBag<>(this);
//初始化连接计数器, 用于统计连接池中的连接数量
this.totalConnections = new AtomicInteger();
//根据是否允许挂起连接池, 初始化锁
this.suspendResumeLock = config.isAllowPoolSuspension() ? new SuspendResumeLock() : SuspendResumeLock.FAUX_LOCK;
//③
//连接池统计
if (config.getMetricsTrackerFactory() != null) {
setMetricsTrackerFactory(config.getMetricsTrackerFactory());
} else {
setMetricRegistry(config.getMetricRegistry());
}
setHealthCheckRegistry(config.getHealthCheckRegistry());
//注册 JMX 相关的 bean
registerMBeans(this);
//④
checkFailFast();
//⑤
ThreadFactory threadFactory = config.getThreadFactory();
this.addConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection adder", threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.closeConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection closer", threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
if (config.getScheduledExecutorService() == null) {
threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory(poolName + " housekeeper", true);
this.houseKeepingExecutorService = new ScheduledThreadPoolExecutor(1, threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.houseKeepingExecutorService.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
this.houseKeepingExecutorService.setRemoveOnCancelPolicy(true);
} else {
this.houseKeepingExecutorService = config.getScheduledExecutorService();
}
//⑥
//默认 30s 运行一次
this.houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(), 0L, HOUSEKEEPING_PERIOD_MS, MILLISECONDS);
//⑦
this.leakTask = new ProxyLeakTask(config.getLeakDetectionThreshold(), houseKeepingExecutorService);
}可以看到代码非常的长,也比较复杂,不要紧,我们慢慢分析。
①初始化父类
super(config);中的 super代表的是com.zaxxer.hikari.pool.PoolBase。PoolBase是一个更接近底层的一个连接池抽象。它里面定义了一些数据库连接相关的配置,比如:是否自动提交事务,是否连接只读,是否使用 JDBC4,网络请求超时时间等。一些比较重要的方法:初始化 JDBC 的dataSource,验证连接是否存活,重置连接默认配置等等。调用super(config);的目的,就是初始化PoolBase中的这些数据库配置。
通过这个super我们可以发现,HikariCP的初始化是逐层传递的,假如某个子类继承了父类,父类又继承了它的父类,那么初始化的时候,是用同一个配置类,先传递到子类,再到父类,再到祖父类,每一层都使用HikariConfig来初始化跟自己相关的配置,我们可以学习这种初始化方式,非常优雅。
具体的PoolBase初始化过程,我们不深入了,不是很复杂,大家可以结合我的代码注释来看一下,注释的非常明白。
②初始化ConcurrentBag
ConcurrentBag是一个通用的池模型的容器,是整个 HikariCP 的核心,我们要单独章节分析,此处大家只是明白这里初始化了用于保存数据库连接的容器,它的内部是一个CopyOnWriteArrayList,用于保存连接。
totalConnections呢,从字面就可以理解,是一个连接的计数器,用于记录连接池中的连接数量。它的类型是AtomicInteger,关于Atomic开头的原子类,我们在《HikariCP源码分析之获取连接流程一》中详细分析过AtomicBoolean的原理,这个是差不多的,大家可以看前面的文章。totalConnections这个计数器,会在向连接池中添加新连接的时候加1,连接池中的连接被关闭之后会减 1。
suspendResumeLock是我们在《HikariCP源码分析之获取连接流程二》中分析的重点,此处不赘述了。这里是创建一个连接池挂起的锁,或者说令牌桶,用于连接池挂起的时候,控制用户不能从连接池获取连接的。如果用户没有开启连接池挂起功能,就创建一个空的锁实现FAUX_LOCK,方便 JIT 将它优化掉。
③监控初始化
我们在之前的获取连接的分析文章中提到过,获取连接的时候,会向监控平台上报自己的状态,这里就是初始化监控平台的相关配置。用户可以自定义监控平台的实现,将它注册到 HikariCP 中,就可以被 HikariCP 调用。
值得一提的是registerMBeans(this);这一句代码。这里是注册 JMX 相关的 MBean,只有配置了数据库的isRegisterMbeans配置项,HikariCP 才会注册MBean,我们才能使用 JMX 在运行期间修改连接池的配置。如果不配置isRegisterMbeans,那么使用 JMX 修改配置会报错。对 JMX 感兴趣的同学,可以自行学习下相关内容。
④快速失败
这里只有一行代码checkFailFast();,但是我们单独拿出来了,这说明这里有点意思。
直接看看代码:
private void checkFailFast() {
if (config.isInitializationFailFast()) {
try {
newConnection().close();
} catch (Throwable e) {
try {
shutdown();
} catch (Throwable ex) {
e.addSuppressed(ex);
}
throw new PoolInitializationException(e);
}
}
}代码看着不少,其实关键的没有多少。isInitializationFailFast是一个 HikariCP的配置项,它的默认值是 true。老规矩,先从字面意思猜测一下,好像是:初始化的时候快速失败的意思。再看一下下面的代码newConnection().close();,这是创建了一个连接,然后立即关闭了呀!综合以上线索,这是什么意思?其实非常好理解。就是在初始化 HikariCP 的时候,建立一个连接,然后立即关闭,如果有报错建立不了,就关闭整个连接池,抛错。
目的就是在启动期间,创建连接来验证关键参数是否有错误,如果不能建立连接,立即抛出错误,方便用户及时发现问题。比如:我们的数据库密码写错了。如果没有这个立即失败的验证,等你上线部署成功之后,第一次获取连接才能发现问题,这不就悲催了嘛,搞不好要挨骂的。
⑤初始化线程池
HikariCP 中有几个线程池:
- closeConnectionExecutor :用于执行关闭底层连接的线程池,只有一个线程,线程任务队列最大是连接池最大连接数,超出队列的任务,会不断重试添加。
- addConnectionExecutor:用于执行添加新连接的线程池,只有一个线程,线程任务队列最大是连接池最大连接数,超出队列的任务,直接抛弃。
- houseKeepingExecutorService:这是一个定时线程池,默认只有一个线程,它的作用比较多:用于执行检测连接泄露、关闭空闲时间超期的连接、回收空闲连接、检测时间回拨。
closeConnectionExecutor的队列任务抛弃策略有点不一样,它会不断重试,是基于连接必须关闭的考虑,其他的任务直接抛弃是影响不大。
这里有两项配置可以影响线程池,一个是scheduledExecutor:用于提供给houseKeepingExecutorService用的线程池,如果用户不自定义,就使用默认的 1 个线程的线程池。另一个是threadFactory:用于生成线程池中的线程,HikariCP 会在生成线程池的时候,调用该线程工厂获取线程。
⑥启动连接管理任务
看代码:
this.houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(), 0L, HOUSEKEEPING_PERIOD_MS, MILLISECONDS);
这里向houseKeepingExecutorService线程池里提交了一个任务:每隔 30 秒,就执行一次HouseKeeper任务。这个任务的功能主要是:检测时间回拨,调整连接池里的连接。什么是时间回拨?比如服务器的系统时间不准,后来用户修改了服务器的系统时间,因为 HikariCP 是对时间敏感的框架,它靠定时任务来管理连接,如果系统时间变了,那么定时任务就不准确了。
有两种情况:
- 一是用户调快了时间,这个时候,HikariCP 什么都不做,因为时间快了,只是加快了定时任务的执行,使连接更早过期,这个对连接池影响不大,因为连接池会自动添加新连接。
- 二是用户调慢了时间,也就是回退了时间。回退时间对 HikariCP 是有极大影响的,比如原来还差 1 秒执行的任务,现在可能要过 15秒之后才能执行了,这可能引发本来该存活时间到期的连接,不会过期了。所以,这个时候,HikariCP 会把连接池中所以的连接都软驱逐掉,使所有的连接都不可用,然后重新创建新连接。
由于HouseKeeper任务比较复杂,我们单独的章节分析。
⑦创建连接泄露检测任务的父任务
看代码:
this.leakTask = new ProxyLeakTask(config.getLeakDetectionThreshold(), houseKeepingExecutorService);
我们在《HikariCP源码分析之获取连接流程三》中分析连接泄露检测时候,提到过,用户获取到每个连接的时候,都会为该连接创建一个连接泄露检测的定时任务,在指定的时间内,抛出连接泄露警告。
在创建连接泄露检测任务的时候,会使用一个父任务的参数,从这个父任务中拿连接泄露的最大时间和用于执行任务的线程池,然后使用这两个参数创建任务。这个父任务,就是在这里创建的,创建的时候就是传了这两个参数:连接泄露的最大时间和用于执行任务的线程池。
至此,HikariDataSource初始化就分析完成了。大家有任何问题,可以提出来,我们一起讨论学习。
边栏推荐
- Tcp/ip test questions (V)
- 揭秘GES超大规模图计算引擎HyG:图切分
- Overview and trend analysis of China's CT examination equipment industry in 2021 [figure]
- [today in history] June 25: the father of notebook was born; Windows 98 release; First commercial use of generic product code
- Guangzhou Sinovel interactive VR panorama brings development to all walks of life
- 初探Oracle全栈虚拟机---GraalVM
- 网络安全检测与防范 测试题(四)
- 一晚上做了一个xpath终结者:xpath-helper-plus
- 广州华锐互动打造VR展厅全景在线虚拟展厅
- R语言plotly可视化:plotly可视化二维直方图等高线图(Basic 2D Histogram Contour)
猜你喜欢

What is an operator?

Guangzhou Sinovel interactive creates VR Exhibition Hall panoramic online virtual exhibition hall
![QQ robot: self forbidden words management of group members [latest beta2 version]](/img/1b/7dcc8ed344c9f62870d76f16b99f1d.png)
QQ robot: self forbidden words management of group members [latest beta2 version]
![In 2021, China's private equity market is growing, and the scale of private equity fund management reaches 19.78 trillion yuan [figure]](/img/e9/ffc5303cb6f0f8e05e93b3342a49b2.jpg)
In 2021, China's private equity market is growing, and the scale of private equity fund management reaches 19.78 trillion yuan [figure]

Idea annotation color modification method (clear)

Sorting out the latest data mining competition scheme!

Under what circumstances do you need to manually write the @bean to the container to complete the implementation class

Tiger DAO VC产品正式上线,Seektiger生态的有力补充

最新數據挖掘賽事方案梳理!

谈谈CNN中的位置和尺度问题
随机推荐
SQL is used for field data types in various databases
Elastic high-performance computing on the cloud supports the rapid development of the life science industry, reducing costs and increasing efficiency
Solidity get quarterly time
Is CICC wealth safe? How long does it take to open an account
Cutting feet to fit shoes - talking about the ramp reconstruction on the track
Guangzhou Sinovel interactive VR panorama brings development to all walks of life
Network security detection and prevention test questions (II)
Analysis of China's medical device industry development environment (PEST) in 2021: the awareness of medical care is enhanced, and the demand for medical device products is also rising [figure]
华为发布两大昇腾计划 推动AI人才发展和科研创新
Divine reversion EA
中金财富安全吗? 开户需要多久
谈谈CNN中的位置和尺度问题
How to sort massive data? How to process data between memory and hard disk?
Kotlin compose terminate todo project Click to edit and modify todo
Training of long and difficult sentences in postgraduate entrance examination day88
Overview and trend analysis of China's CT examination equipment industry in 2021 [figure]
Analysis on the development trend of China's intense pulsed light equipment industry in 2021: the market scale is growing, and the proportion of imported brands is large [figure]
Differences and relations between sequential table and array (easy to confuse), linear table and linked list
最新數據挖掘賽事方案梳理!
Guangzhou Sinovel interactive creates VR Exhibition Hall panoramic online virtual exhibition hall