赞
踩
this.houseKeeperTask = houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(), 100L, housekeepingPeriodMs, MILLISECONDS);
这段代码是 HikariCP 中用于填充连接池至 minimumIdle
配置值的核心逻辑。让我们逐行分析一下这段代码:
最小空闲连接数, 保持MinimumIdle个空闲连接,
举例,(1)MaximumPoolSize = 100, MinimumIdle= 20, IdleConnections = 0, TotalConnections= 0,则创建20个空闲连接。
(2)MaximumPoolSize = 100, MinimumIdle= 20, IdleConnections = 0, TotalConnections= 20,则创建20个空闲连接。
(3)MaximumPoolSize = 30, MinimumIdle= 20, IdleConnections = 0, TotalConnections= 20,则创建10个空闲连接。
/**
* Fill pool up from current idle connections (as they are perceived at the point of execution) to minimumIdle connections.
*/
private synchronized void fillPool()
{
final int connectionsToAdd = Math.min(config.getMaximumPoolSize() - getTotalConnections(), config.getMinimumIdle() - getIdleConnections())//配置的最小空闲连接数-已空闲的连接数
- addConnectionQueueReadOnlyView.size();
if (connectionsToAdd <= 0) logger.debug("{} - Fill pool skipped, pool is at sufficient level.", poolName);
for (int i = 0; i < connectionsToAdd; i++) {
addConnectionExecutor.submit((i < connectionsToAdd - 1) ? poolEntryCreator : postFillPoolEntryCreator);
}
}
这部分代码首先计算需要添加多少个连接到连接池中,以达到 minimumIdle
的配置值。这里使用了 Math.min
函数,确保添加的连接数不会超过 maximumPoolSize
的限制。同时,它还减去了已经正在被创建但尚未加入池中的连接数(addConnectionQueueReadOnlyView.size()
),以防止重复计算。
for (int i = 0; i < connectionsToAdd; i++) {
addConnectionExecutor.submit((i < connectionsToAdd - 1) ? poolEntryCreator : postFillPoolEntryCreator);
}
}
这部分代码则通过一个循环,将连接创建的任务提交给一个执行器(addConnectionExecutor
)。这个执行器会异步地创建新的数据库连接,并将它们添加到连接池中。这里值得注意的是,最后一个连接的创建任务可能使用不同的创建者(postFillPoolEntryCreator
),这可能是为了执行一些在达到 minimumIdle
后需要进行的特殊操作,比如触发某些回调或清理任务。
总的来说,这段代码展示了 HikariCP 如何智能地管理连接池的大小,确保连接池中有足够的空闲连接,同时又不会无谓地占用过多资源。它通过异步的方式创建连接,避免了阻塞主线程,同时也确保了连接的创建是在资源允许的情况下进行的,不会导致资源过度消耗。
/** * Creating and adding poolEntries (connections) to the pool. */ private final class PoolEntryCreator implements Callable<Boolean> { private final String loggingPrefix; PoolEntryCreator(String loggingPrefix) { this.loggingPrefix = loggingPrefix; } @Override public Boolean call() { long sleepBackoff = 250L; while (poolState == POOL_NORMAL && shouldCreateAnotherConnection()) { final PoolEntry poolEntry = createPoolEntry(); if (poolEntry != null) { connectionBag.add(poolEntry); logger.debug("{} - Added connection {}", poolName, poolEntry.connection); if (loggingPrefix != null) { logPoolState(loggingPrefix); } return Boolean.TRUE; } // failed to get connection from db, sleep and retry if (loggingPrefix != null) logger.debug("{} - Connection add failed, sleeping with backoff: {}ms", poolName, sleepBackoff); quietlySleep(sleepBackoff); sleepBackoff = Math.min(SECONDS.toMillis(10), Math.min(connectionTimeout, (long) (sleepBackoff * 1.5))); } // Pool is suspended or shutdown or at max size return Boolean.FALSE; } /** * We only create connections if we need another idle connection or have threads still waiting * for a new connection. Otherwise we bail out of the request to create. * * @return true if we should create a connection, false if the need has disappeared */ private synchronized boolean shouldCreateAnotherConnection() { return getTotalConnections() < config.getMaximumPoolSize() && (connectionBag.getWaitingThreadCount() > 0 || getIdleConnections() < config.getMinimumIdle()); } }
HikariCP 是一个高性能的 JDBC 数据库连接池,它被设计为简单、快速和可靠。HikariCP 提供了一系列的配置参数来微调其行为,以便满足不同应用程序的需求。下面是一些主要的配置参数及其解释:
maximumPoolSize
:
minimumIdle
:
idleTimeout
:
minimumIdle
数量未达到。connectionTimeout
:
maxLifetime
:
autoCommit
:
dataSourceClassName
或 dataSource
:
javax.sql.DataSource
接口的类。validationQuery
:
testOnBorrow
, testOnReturn
, testWhileIdle
:
registerMbeans
:
metricRegistry
:
以上参数可以通过不同的方式设置,如在 Spring Boot 的 application.properties
文件中,或者在 Java 代码中通过构造函数或 setter 方法传递给 HikariConfig
实例。正确的配置取决于应用程序的具体需求和环境。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。