网站首页 > 博客文章 正文
HikariCP,以其卓越的性能和低延迟连接池技术,正成为Java开发者的优选。在这篇文章中,我将深入探讨其核心特性、最佳实践以及如何通过HikariCP优化数据库连接。无论您是数据库专家还是新手,HikariCP都能为您的项目带来显著的性能提升。
肖哥弹架构 跟大家“弹弹” 连接池使用,需要代码关注
欢迎 点赞,关注,评论。
关注公号Solomon肖哥弹架构获取更多精彩内容
历史热点文章
- 28个验证注解,通过业务案例让你精通Java数据校验(收藏篇)
- Java 8函数式编程全攻略:43种函数式业务代码实战案例解析(收藏版)
- 69 个Spring mvc 全部注解:真实业务使用案例说明(必须收藏)
- 24 个Spring bean 全部注解:真实业务使用案例说明(必须收藏)
- MySQL索引完全手册:真实业务图文讲解17种索引运用技巧(必须收藏)
- 一个项目代码讲清楚DO/PO/BO/AO/E/DTO/DAO/ POJO/VO
0、HikariCP连接池管理策略
连接池管理策略说明
- 初始化连接池:根据配置参数初始化连接池。
- 检查连接状态:在每次连接使用前,检查连接是否有效。
- 使用连接执行操作:如果连接有效,执行数据库操作。
- 尝试自动重连:如果连接无效,尝试自动重新连接到数据库。
- 标记为无效并从池中移除:如果重连失败,标记连接为无效并从连接池中移除。
- 操作完成后返回连接:操作完成后,将连接返回到连接池。
- 检查空闲连接超时:定期检查空闲连接是否超时。
- 关闭连接:如果连接空闲超时,关闭连接以释放资源。
- 保持连接以便重用:如果连接未超时,保持连接以便后续重用。
- 尝试创建新连接:如果连接池中的连接不足,尝试创建新的连接。
- 连接池监控:监控连接池的状态和性能。
- 定期健康检查:定期对连接池中的连接执行健康检查。
- 记录性能指标:记录连接池的性能指标,如活跃连接数、等待时间等。
- 监控慢查询:监控并记录执行时间超过阈值的慢查询。
- 生成监控报告:生成连接池的监控报告,提供性能分析和优化建议。
1、HikariCP功能划分
- 应用层(业务代码层面) :在应用层,开发者可以通过配置文件或代码来配置 HikariCP 的行为。这些配置通常包括数据库连接的基本信息(如URL、用户名、密码)、连接池的大小、超时设置、心跳检测等。这些配置可以通过 HikariCP 提供的 API 在业务代码中直接设置,也可以通过配置文件(如 hikari.properties 或 application.properties)来实现。
- 系统层(基础设施层面) :在系统层,HikariCP 内部的机制如连接的创建、维护、监控和故障恢复等是自动进行的,不需要开发者在业务代码中干预。这些机制确保了连接池的高效和稳定运行。
消费者在业务代码中可以配置的功能:
- 数据源配置:在业务代码中,开发者可以使用 HikariCP 提供的 HikariConfig 类来配置数据源,例如设置 JDBC URL、用户名、密码等。
- 连接池参数:可以设置连接池的各种参数,如最大连接数、最小空闲连接数、连接超时等。
- 心跳检测:配置心跳检测的 SQL 语句,以确保数据库连接的活跃性。
- 监控和诊断:启用或配置 HikariCP 的监控和诊断功能,例如慢查询日志记录。
- 多租户支持:在多租户环境中,为每个租户配置独立的数据源。
- 整合框架:将 HikariCP 与 Spring 等框架整合,利用框架提供的依赖注入和配置管理功能。
2、HikariCP 配置属性说明
常用配置选项
- driverClassName: 数据库驱动的完全限定名。
- jdbcUrl: 数据库的 JDBC URL。
- username: 数据库的用户名。
- password: 数据库的密码。
- maximumPoolSize: 连接池中最大的连接数。
- minimumIdle: 连接池中最小的空闲连接数。
- idleTimeout: 连接在池中空闲时的超时时间(毫秒)。
- maxLifetime: 连接在池中的最大生命周期(毫秒)。
- connectionTimeout: 获取连接时的超时时间(毫秒)。
- autoCommit: 是否自动提交。
不常用配置选项
- connectionTestQuery: 用于测试连接是否有效的 SQL 查询。
- connectionInitSql: 每次连接初始化时执行的 SQL 语句。
- dataSourceProperties: 用于设置其他 JDBC 数据源属性的属性映射。
- readOnly: 是否只读连接。
- isolateInternalQueries: 是否隔离内部查询。
- allowPoolSuspension: 是否允许连接池挂起。
- registerMbeans: 是否注册 JMX 管理 Bean。
- catalog: 数据库的目录。
- transactionIsolation: 事务隔离级别。
- initializationFailTimeout: 初始化失败时的超时时间。
- initSQL: 初始化时执行的 SQL 语句。
- jdbc4ConnectionTest: 是否使用 JDBC 4.0 的连接测试方法。
- leakDetectionThreshold: 检测连接泄漏的阈值(毫秒)。
- metricRegistry: 用于注册度量的度量注册表。
- healthCheckRegistry: 用于注册健康检查的注册表。
- dataSource: 用于提供自定义数据源。
- scheduledExecutorService: 自定义用于周期性任务的 ScheduledExecutorService。
- threadFactory: 自定义用于创建新线程的 ThreadFactory。
- passwordCallback: 用于获取密码的 Callback。
- dataSourceClassName: 自定义数据源类的名称。
HikariCP配置属性代码:
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class HikariCPFullConfigExample {
public static void main(String[] args) {
HikariConfig config = new HikariConfig();
// 常用配置
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
config.setUsername("user");
config.setPassword("password");
config.setMaximumPoolSize(10);
config.setMinimumIdle(2);
config.setIdleTimeout(300000); // 5 minutes
config.setMaxLifetime(1800000); // 30 minutes
config.setConnectionTimeout(30000); // 30 seconds
// 不常用配置
config.setConnectionTestQuery("SELECT 1");
config.setReadOnly(false);
config.setIsolateInternalQueries(false);
config.setAllowPoolSuspension(true);
config.setRegisterMbeans(true);
config.setCatalog("mycatalog");
config.setTransactionIsolation("TRANSACTION_READ_COMMITTED");
config.setInitializationFailTimeout(1);
config.setInitSQL("SET NAMES utf8mb4");
config.setJdbc4ConnectionTest(true);
config.setLeakDetectionThreshold(60000); // 60 seconds
// 创建 HikariDataSource
HikariDataSource dataSource = new HikariDataSource(config);
// 使用 dataSource 获取连接
try (Connection connection = dataSource.getConnection()) {
// 执行数据库操作
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭 dataSource
dataSource.close();
}
}
}
HikariCP通用配置属性代码:
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class HikariCPExample {
public static void main(String[] args) {
// 创建 HikariCP 配置对象
HikariConfig config = new HikariConfig();
// 设置 JDBC 驱动类名
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
// 设置 JDBC URL
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
// 设置数据库用户名
config.setUsername("user");
// 设置数据库密码
config.setPassword("password");
// 设置连接池最大连接数(默认值:10)
config.setMaximumPoolSize(20);
// 设置连接池最小空闲连接数(默认值:10)
config.setMinimumIdle(5);
// 设置连接池中连接的空闲超时时间(默认值:600000ms,即10分钟)
config.setIdleTimeout(300000); // 5 minutes
// 设置连接的最大生命周期(默认值:1800000ms,即30分钟)
config.setMaxLifetime(900000); // 15 minutes
// 设置连接超时时间(默认值:30000ms,即30秒)
config.setConnectionTimeout(5000); // 5 seconds
// 设置自动提交(默认值:true)
config.setAutoCommit(true);
// 设置隔离级别(默认值:READ_COMMITTED)
config.setTransactionIsolation("TRANSACTION_READ_COMMITTED");
// 设置数据库连接参数
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
// 设置连接池的注册 JMX 管理(默认值:false)
config.setRegisterMbeans(true);
// 设置自定义初始化 SQL 语句
config.setConnectionInitSql("SET NAMES utf8mb4");
// 创建 HikariDataSource 对象
HikariDataSource dataSource = new HikariDataSource(config);
// 使用 HikariDataSource 获取数据库连接
try (Connection connection = dataSource.getConnection()) {
System.out.println("Obtained connection: " + connection);
// 创建 Statement 对象
try (Statement statement = connection.createStatement()) {
// 创建 ResultSet 对象
try (ResultSet resultSet = statement.executeQuery("SELECT 1")) {
// 处理查询结果
while (resultSet.next()) {
System.out.println("Query result: " + resultSet.getInt(1));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
// 关闭 HikariDataSource
dataSource.close();
}
}
3、 特殊场景下的配置
3.1 读写平衡配置
在读写操作相对均衡的项目中,HikariCP 的默认配置通常就能提供良好的性能。但是,可以根据实际的负载情况调整连接池大小和超时设置。
config.setMaximumPoolSize(Runtime.getRuntime().availableProcessors() * 2);
config.setMinimumIdle(2);
config.setIdleTimeout(60000); // 1 minute
config.setMaxLifetime(1800000); // 30 minutes
合理性:
- maximumPoolSize 设置为 CPU 核心数的两倍,可以充分利用多核优势。
- idleTimeout 和 maxLifetime 提供了合理的连接重用和自动清理。
3.2 读多写少配置
对于读操作远多于写操作的项目,可以增加连接池大小,以便更多并发读取,同时确保写操作不会被饿死。
config.setMaximumPoolSize(50); // 根据实际负载调整
config.setMinimumIdle(10);
config.setIdleTimeout(60000); // 1 minute
config.setMaxLifetime(1800000); // 30 minutes
config.setConnectionTestQuery("SELECT 1"); // 确保连接有效性
合理性:
- 增加 maximumPoolSize 以支持更多的并发读操作。
- setConnectionTestQuery 确保长时间运行的连接仍然有效。
3.3 写多读少配置
在写操作多于读操作的项目中,可能需要更少的连接数,因为写操作通常更耗时,占用连接时间更长。
config.setMaximumPoolSize(10); // 较小的连接池
config.setMinimumIdle(2);
config.setIdleTimeout(180000); // 3 minutes
config.setMaxLifetime(900000); // 15 minutes
合理性:
- 较小的 maximumPoolSize 避免过多的连接占用资源。
- 较长的 idleTimeout 和 maxLifetime 允许写操作有更多时间完成。
3.4 高并发配置
在高并发场景下,需要确保连接池能够快速响应连接请求,同时避免过多的线程竞争。
config.setMaximumPoolSize(100); // 根据并发需求调整
config.setMinimumIdle(20);
config.setIdleTimeout(10000); // 10 seconds
config.setMaxLifetime(600000); // 10 minutes
config.setConnectionTimeout(5000); // 5 seconds
合理性:
- 较大的 maximumPoolSize 和 minimumIdle 确保在高峰时段有足够的连接可用。
- 较短的 idleTimeout 和 maxLifetime 可以快速回收和重用连接。
- 较短的 connectionTimeout 避免在连接获取上等待过长时间。
3.5 多租户管理
一个多租户应用程序,每个租户都有自己的数据库。我们需要为每个租户创建一个独立的 HikariCP 数据源。
步骤 1: 创建数据源工厂
首先,我们可以创建一个工厂类,用于为每个租户生成配置好的 HikariCP 数据源。
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
public class DataSourceFactory {
private static final Map<String, DataSource> dataSources = new HashMap<>();
public static DataSource getDataSource(String tenantId) {
return dataSources.computeIfAbsent(tenantId, DataSourceFactory::createDataSource);
}
private static DataSource createDataSource(String tenantId) {
HikariConfig config = new HikariConfig();
// 假设我们有一个方法来获取每个租户的数据库连接信息
String jdbcUrl = "jdbc:mysql://localhost:3306/" + tenantId + "_db";
String username = "user_" + tenantId;
String password = "password_" + tenantId;
config.setJdbcUrl(jdbcUrl);
config.setUsername(username);
config.setPassword(password);
config.setMaximumPoolSize(10); // 根据租户需求调整
config.setMinimumIdle(2);
config.setIdleTimeout(300000); // 5 minutes
config.setMaxLifetime(1800000); // 30 minutes
config.setConnectionTimeout(5000); // 5 seconds
// 其他配置...
HikariDataSource dataSource = new HikariDataSource(config);
return dataSource;
}
}
步骤 2: 使用数据源
在应用程序中,根据当前租户的 ID 获取对应的数据源,并使用它来执行数据库操作。
public class MultiTenantService {
public void performDatabaseOperation(String tenantId) {
DataSource dataSource = DataSourceFactory.getDataSource(tenantId);
try (Connection connection = dataSource.getConnection()) {
// 执行数据库操作
// ...
} catch (SQLException e) {
e.printStackTrace();
}
}
}
合理性:
- 数据隔离:每个租户都有自己的数据源,确保了数据的隔离性。
- 性能优化:可以根据每个租户的负载情况调整连接池的大小和其他参数。
- 灵活性:在多租户环境中,可以灵活地为每个租户配置不同的数据库连接信息。
3.6 监控和诊断
HikariCP 提供了监控和诊断功能,可以帮助开发者监控数据库连接池的状态和性能,以及诊断潜在的问题。
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.codahale.metrics.MetricRegistry;
public class HikariCPMonitoringConfig {
public static void main(String[] args) {
HikariConfig config = new HikariConfig();
// 数据库连接配置
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
config.setUsername("user");
config.setPassword("password");
// 监控和诊断配置
config.setLogSlowQueries(true);
config.setSlowQueryThreshold(2000); // 记录超过2秒的查询
// 指标收集
MetricRegistry metricRegistry = new MetricRegistry();
config.setMetricRegistry(metricRegistry);
// 健康检查
config.setHealthCheckRegistry(metricRegistry);
config.setConnectionTestQuery("SELECT 1");
// JMX 管理
config.setRegisterMbeans(true);
// 自动重连
config.setAutoReconnect(true);
// 线程池配置
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
config.setScheduledExecutorService(executorService);
// 创建 HikariDataSource
HikariDataSource dataSource = new HikariDataSource(config);
// 使用 dataSource 获取连接
try (Connection connection = dataSource.getConnection()) {
// 执行数据库操作
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭 dataSource
dataSource.close();
}
}
}
配置说明:
- 慢查询日志:帮助开发者识别和优化慢查询,提高数据库性能。
- 指标收集:提供实时的性能指标,便于监控和分析。
- 健康检查:确保连接池中的连接都是可用的,避免在应用程序中出现无效连接。
- JMX 管理:允许远程监控和管理,提高运维效率。
- 自动重连:提高系统的稳定性和可靠性。
- 线程池配置:自定义线程池可以更好地控制定期任务的执行。
总结
HikariCP 被认为是效率最高的 JDBC 连接池之一,主要是因为以下几个核心原因:
- 优化的连接获取:HikariCP 优化了连接获取的路径,减少了不必要的延迟,使得获取数据库连接的速度非常快。
- 快速的故障恢复:它能够快速检测并恢复数据库连接,减少了因连接问题导致的系统故障时间。
- 低开销的维护:HikariCP 的设计注重资源的高效利用,减少了内存和 CPU 的开销,使得连接池的维护成本较低。
- 自适应的连接管理:它能够根据应用程序的实际需求自动调整连接池的大小,从而在保证性能的同时,避免资源浪费。
- 高效的垃圾回收:HikariCP 通过减少对象创建和销毁的次数,以及优化的缓存策略,减少了垃圾回收的压力。
- 先进的并发控制:它使用了高效的并发控制机制,避免了多线程环境下的锁竞争,提高了并发处理能力。
- 细致的配置选项:提供了丰富的配置选项,允许开发者根据具体的应用场景和性能要求进行细致的调优。
- 自动监控和诊断:内置了监控和诊断工具,可以帮助开发者及时发现并解决性能瓶颈和潜在问题。
- 与现代硬件和JVM的协同:HikariCP 能够很好地利用现代硬件和 JVM 的特性,如 NUMA 架构和 JIT 编译器优化。
- 合理的默认配置:提供了合理的默认配置,使得即使在没有进行精细调优的情况下,也能提供良好的性能。
- 轻量级的实现:相比于其他连接池实现,HikariCP 更加轻量级,启动和运行时的资源占用更少。
这些因素共同作用,使得 HikariCP 在性能上表现出色,成为了许多开发者和企业的首选连接池解决方案,具体细节会在下一篇文档中详细分析。
猜你喜欢
- 2024-10-17 SpringBoot+Vue3+MySQL集群 开发健康体检双系统(完结)
- 2024-10-17 再有人问你数据库连接池的原理,这篇文章甩给他!
- 2024-10-17 详解Spring Boot并发处理能力:理论与参数设置实践
- 2024-10-17 数据库连接池有什么用?springboot中如何使用?
- 2024-10-17 谈谈高并发系统的一些解决方案(高并发系统设计的三大目标)
- 2024-10-17 微服务事务管理艺术:Spring Boot 集成 Seata 深度指南
- 2024-10-17 阿里巴巴开源数据库jdbc连接池 Druid 1.1.18 发布
- 2024-10-17 【架构之路】提升后端接口性能的实战技巧
- 2024-10-17 「解密」有人要将“高并发”拉下“神坛”!
- 2024-10-17 MySQL连接优化是数据库性能调优的重要一环
你 发表评论:
欢迎- 371℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 369℃用AI Agent治理微服务的复杂性问题|QCon
- 360℃初次使用IntelliJ IDEA新建Maven项目
- 352℃Maven技术方案最全手册(mavena)
- 349℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 348℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 346℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 344℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)