hikaripool信息_HikariPool源码(三)资源池动态伸缩「建议收藏」

hikaripool信息_HikariPool源码(三)资源池动态伸缩「建议收藏」Java极客|作者/铿然一叶这是Java极客的第54篇原创文章1.资源池的动态伸缩1.为了提升资源池的性能,需要设置最小闲置资源数量,在资源池初始化时完成初始化;而当使用的资源超过最小闲置资源数,消费者释放回池中超过一定时间后要收缩到最小闲置资源数。2.为了避免无限申请资源导致超出负载,需要设置最大资源数,池中资源不能超出最大资源数。2.动态伸缩相关类结构职责说明:类职责Hou…

大家好,又见面了,我是你们的朋友全栈君。

hikaripool信息_HikariPool源码(三)资源池动态伸缩「建议收藏」

Java极客  |  作者  /  铿然一叶

这是Java极客的第 54 篇原创文章

1.资源池的动态伸缩

1.为了提升资源池的性能,需要设置最小闲置资源数量,在资源池初始化时完成初始化;而当使用的资源超过最小闲置资源数,消费者释放回池中超过一定时间后要收缩到最小闲置资源数。

2.为了避免无限申请资源导致超出负载,需要设置最大资源数,池中资源不能超出最大资源数。

2.动态伸缩相关类结构

hikaripool信息_HikariPool源码(三)资源池动态伸缩「建议收藏」

职责说明:

职责

HouseKeeper

实现了Runnable接口,负责池资源的动态伸缩。

ScheduledExecutorService

负责调度HouseKeeper。

ScheduledFuture

由ScheduledExecutorService调度返回,可以终止HouseKeeper的执行。

HikariPool

负责在构造器中初始化和调用以上类。

3.源码

3.1.HikariPool

// 初始化ScheduledExecutorService

this.houseKeepingExecutorService = initializeHouseKeepingExecutorService();

// 调度HouseKeeper, 延迟并周期性调度

this.houseKeeperTask = houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(), 100L, housekeepingPeriodMs, MILLISECONDS);

复制代码

3.2.HouseKeeper

private final class HouseKeeper implements Runnable{

private volatile long previous = plusMillis(currentTime(), -housekeepingPeriodMs);

@Override

public void run(){

try {

// refresh values in case they changed via MBean

connectionTimeout = config.getConnectionTimeout();

validationTimeout = config.getValidationTimeout();

leakTaskFactory.updateLeakDetectionThreshold(config.getLeakDetectionThreshold());

catalog = (config.getCatalog() != null && !config.getCatalog().equals(catalog)) ? config.getCatalog() : catalog;

final long idleTimeout = config.getIdleTimeout();

final long now = currentTime();

// Detect retrograde time, allowing +128ms as per NTP spec.

if (plusMillis(now, 128) < plusMillis(previous, housekeepingPeriodMs)) {

logger.warn(“{} – Retrograde clock change detected (housekeeper delta={}), soft-evicting connections from pool.”,

poolName, elapsedDisplayString(previous, now));

previous = now;

softEvictConnections();

return;

}

else if (now > plusMillis(previous, (3 * housekeepingPeriodMs) / 2)) {

// No point evicting for forward clock motion, this merely accelerates connection retirement anyway

logger.warn(“{} – Thread starvation or clock leap detected (housekeeper delta={}).”, poolName, elapsedDisplayString(previous, now));

}

previous = now;

String afterPrefix = “Pool “;

if (idleTimeout > 0L && config.getMinimumIdle() < config.getMaximumPoolSize()) {

logPoolState(“Before cleanup “);

afterPrefix = “After cleanup “;

// 获取未使用的资源

final List notInUse = connectionBag.values(STATE_NOT_IN_USE);

// 未使用资源大于配置的最小闲置资源则关闭多余资源

int toRemove = notInUse.size() – config.getMinimumIdle();

for (PoolEntry entry : notInUse) {

if (toRemove > 0 && elapsedMillis(entry.lastAccessed, now) > idleTimeout && connectionBag.reserve(entry)) {

closeConnection(entry, “(connection has passed idleTimeout)”);

toRemove–;

}

}

}

logPoolState(afterPrefix);

// 除了动态减少资源,这里动态扩容资源

fillPool(); // Try to maintain minimum connections

}

catch (Exception e) {

logger.error(“Unexpected exception in housekeeping task”, e);

}

}

}

复制代码

动态扩容资源:

//HikariPool.java

private synchronized void fillPool(){

final int connectionsToAdd = Math.min(config.getMaximumPoolSize() – getTotalConnections(), config.getMinimumIdle() – getIdleConnections())

– addConnectionQueue.size();

for (int i = 0; i < connectionsToAdd; i++) {

addConnectionExecutor.submit((i < connectionsToAdd – 1) ? poolEntryCreator : postFillPoolEntryCreator);

}

}

复制代码

3.3.ConcurrentBag

在ConcurrentBag中释放资源时之会修改资源的状态,不会去改变资源池可用资源数量。

public void requite(final T bagEntry){

// 这里只是修改资源状态,并不减少资源池中可用资源数量。

bagEntry.setState(STATE_NOT_IN_USE);

for (int i = 0; waiters.get() > 0; i++) {

if (bagEntry.getState() != STATE_NOT_IN_USE || handoffQueue.offer(bagEntry)) {

return;

}

else if ((i & 0xff) == 0xff) { // 0xff 是255, 每隔256进去一次

parkNanos(MICROSECONDS.toNanos(10));

}

else {

yield();

}

}

final List threadLocalList = threadList.get();

if (threadLocalList.size() < 50) {

threadLocalList.add(weakThreadLocals ? new WeakReference<>(bagEntry) : bagEntry);

}

}

复制代码

4.总结

资源池在初始化时初始化最小资源数。

资源的动态伸缩可以通过JUC工具ScheduledExecutorService调度线程完成,而不需要额外使用第三方定时器。

消费者释放资源时并不会立即减少资源池可用资源数量,因为很可能其他的消费者又会申请资源,为了避免减少无谓的创建资源操作,释放的资源应该在超过一定时间后才真正关闭。

end.

hikaripool信息_HikariPool源码(三)资源池动态伸缩「建议收藏」

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/152357.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 怎样使用父组件向子组件传值【 必看】

    怎样使用父组件向子组件传值【 必看】呃呃,首先小仙女初学Vue传值的时候,是费尽了脑汁,不知道怎么回事。终于,功夫不负有心人,把他弄明白了,如有错误,请多指教!!首先在学习Vue的框架开发的项目过程中,会经常会用到组件来管理不同的功能,有些公共的东西会就会被抽取出来,当做组件去使用。这时必然会产生一些疑问和需求?比如一个组件调用另一个组件作为自己的子组件,那么我们如何进行给子组件进行传值呢?就先和小编一起探究一下吧!父向子传递…

  • 三层架构 银行管理系统

    三层架构 银行管理系统

  • 格式化hdfs的命令_hadoop的启动命令

    格式化hdfs的命令_hadoop的启动命令总结:上传文件:put、copyFromLocal、moveFromLocal下载文件:get、copyToLocal、moveToLocal查看文件:text、cat、tail合并文件:getmerge命令详解HDFS命令基本格式:hadoopfs-cmd<args>表格:选项名称使用格式含义-ls-ls查看指定路径的当前目录结构-lsr-lsr递归查看指定路径的目录结…

  • 从【MySQL server has gone away】说起[通俗易懂]

    从【MySQL server has gone away】说起

  • 苹果备忘录导出到android,怎么把苹果的备忘录转到安卓系统?[通俗易懂]

    苹果备忘录导出到android,怎么把苹果的备忘录转到安卓系统?[通俗易懂]原标题:怎么把苹果的备忘录转到安卓系统?我的闺蜜小张之前一直使用的是苹果手机,她使用过苹果6s和iPhone8plus,不过最近这次在更换手机的时候,小张为了支持国产手机,就入手了一款华为手机。在试用了一两天的新华为手机后,小张表示这款华为手机也是比较好用的,于是小张就想把之前的苹果手机备忘录内容转到安卓系统中以便继续使用。彩色便签不过小张发现苹果自带备忘录内容是不支持授权一键导出所有数据的,这…

  • A星算法详解(个人认为最详细,最通俗易懂的一个版本)「建议收藏」

    A星算法详解(个人认为最详细,最通俗易懂的一个版本)「建议收藏」A*寻路算法原文地址:http://www.gamedev.net/reference/articles/article2003.asp概述虽然掌握了A*算法的人认为它容易,但是对于初学者来说,A*算法还是很复杂的。搜索区域(TheSearchArea)我们假设某人要从A点移动到B点,但是这两点之间被一堵墙隔开。如图1,绿色是A,红色是B

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号