重庆北碚网站建设,制作流程图软件,山东省建设厅网站多少,濮阳建站公司流程1. 概述
在我们的项目中#xff0c;数据库连接池基本是必不可少的组件。在目前数据库连接池的选型中#xff0c;主要是
Druid #xff0c;为监控而生的数据库连接池。HikariCP #xff0c;号称性能最好的数据库连接池。
至于怎么选择#xff0c;两者都非常优秀#x… 1. 概述
在我们的项目中数据库连接池基本是必不可少的组件。在目前数据库连接池的选型中主要是
Druid 为监控而生的数据库连接池。HikariCP 号称性能最好的数据库连接池。
至于怎么选择两者都非常优秀不用过多纠结。
Spring Boot 2.X 版本默认采用 HikariCP 。阿里大规模采用 Druid 。
当然如下有一些资料胖友可以阅读参考
《Druid 连接池介绍》《为什么 HikariCP 被号称为性能最好的 Java 数据库连接池如何配置使用》《alibaba/druid pool analysis》 一个小小的“撕逼”。
下面我们来进行 HikariCP 和 Druid 的入门会配置单数据源和多数据源情况下的连接池。
2. HikariCP 单数据源 示例代码对应仓库lab-19-datasource-pool-hikaricp-single 。 在本小节我们会使用配置一个数据源的 HikariCP 连接池。 艿艿推荐入门后可以看看 HikariCP 的文档https://github.com/brettwooldridge/HikariCP/wiki 。 2.1 引入依赖
在 pom.xml 文件中引入相关依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.1.3.RELEASE/versionrelativePath/ !-- lookup parent from repository --/parentmodelVersion4.0.0/modelVersionartifactIdlab-19-datasource-pool-hikaricp-single/artifactIddependencies!-- 实现对数据库连接池的自动化配置 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependency !-- 本示例我们使用 MySQL --groupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.48/version/dependency!-- 方便等会写单元测试 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependencies/project
无需主动引入 HikariCP 的依赖。因为在 Spring Boot 2.X 中spring-boot-starter-jdbc 默认引入 com.zaxxer.HikariCP 依赖。
2.2 应用配置文件
在 application.yml 中添加 HikariCP 配置如下 spring:# datasource 数据源配置内容对应 DataSourceProperties 配置属性类datasource:url: jdbc:mysql://127.0.0.1:3306/test?useSSLfalseuseUnicodetruecharacterEncodingUTF-8driver-class-name: com.mysql.jdbc.Driverusername: root # 数据库账号password: # 数据库密码# HikariCP 自定义配置对应 HikariConfig 配置属性类hikari:minimum-idle: 10 # 池中维护的最小空闲连接数默认为 10 个。maximum-pool-size: 10 # 池中最大连接数包括闲置和使用中的连接默认为 10 个。
在 spring.datasource 配置项下我们可以添加数据源的通用配置。在 spring.datasource.hikari 配置项下我们可以添加 HikariCP 连接池的自定义配置。然后 DataSourceConfiguration.Hikari 会自动化配置 HikariCP 连接池。
HikariCP 更多配置项可以看看如下表格s FROM 《HikariCP 连接池及其在 Spring Boot 中的配置》 配置项描述构造器默认值默认配置validate之后的值validate重置autoCommit自动提交从池中返回的连接truetrue-connectionTimeout等待来自池的连接的最大毫秒数SECONDS.toMillis(30) 3000030000如果小于250毫秒则被重置回30秒idleTimeout连接允许在池中闲置的最长时间MINUTES.toMillis(10) 600000600000如果idleTimeout1秒maxLifetime 且 maxLifetime0则会被重置为0代表永远不会退出如果idleTimeout!0且小于10秒则会被重置为10秒maxLifetime池中连接最长生命周期MINUTES.toMillis(30) 18000001800000如果不等于0且小于30秒则会被重置回30分钟connectionTestQuery如果您的驱动程序支持JDBC4我们强烈建议您不要设置此属性nullnull-minimumIdle池中维护的最小空闲连接数-110minIdle0或者minIdlemaxPoolSize,则被重置为maxPoolSizemaximumPoolSize池中最大连接数包括闲置和使用中的连接-110如果maxPoolSize小于1则会被重置。当minIdle0被重置为DEFAULT_POOL_SIZE则为10;如果minIdle0则重置为minIdle的值metricRegistry该属性允许您指定一个 Codahale / Dropwizard MetricRegistry 的实例供池使用以记录各种指标nullnull-healthCheckRegistry该属性允许您指定池使用的Codahale / Dropwizard HealthCheckRegistry的实例来报告当前健康信息nullnull-poolName连接池的用户定义名称主要出现在日志记录和JMX管理控制台中以识别池和池配置nullHikariPool-1-initializationFailTimeout如果池无法成功初始化连接则此属性控制池是否将 fail fast11-isolateInternalQueries是否在其自己的事务中隔离内部池查询例如连接活动测试falsefalse-allowPoolSuspension控制池是否可以通过JMX暂停和恢复falsefalse-readOnly从池中获取的连接是否默认处于只读模式falsefalse-registerMbeans是否注册JMX管理BeanMBeansfalsefalse-catalog为支持 catalog 概念的数据库设置默认 catalogdriver defaultnull-connectionInitSql该属性设置一个SQL语句在将每个新连接创建后将其添加到池中之前执行该语句。nullnull-driverClassNameHikariCP将尝试通过仅基于jdbcUrl的DriverManager解析驱动程序但对于一些较旧的驱动程序还必须指定driverClassNamenullnull-transactionIsolation控制从池返回的连接的默认事务隔离级别nullnull-validationTimeout连接将被测试活动的最大时间量SECONDS.toMillis(5) 50005000如果小于250毫秒则会被重置回5秒leakDetectionThreshold记录消息之前连接可能离开池的时间量表示可能的连接泄漏00如果大于0且不是单元测试则进一步判断(leakDetectionThreshold SECONDS.toMillis(2) or (leakDetectionThreshold maxLifetime maxLifetime 0)会被重置为0 . 即如果要生效则必须0而且不能小于2秒而且当maxLifetime 0时不能大于maxLifetimedataSource这个属性允许你直接设置数据源的实例被池包装而不是让HikariCP通过反射来构造它nullnull-schema该属性为支持模式概念的数据库设置默认模式driver defaultnull-threadFactory此属性允许您设置将用于创建池使用的所有线程的java.util.concurrent.ThreadFactory的实例。nullnull-scheduledExecutor此属性允许您设置将用于各种内部计划任务的java.util.concurrent.ScheduledExecutorService实例nullnull- 2.3 Application
创建 Application.java 类配置 SpringBootApplication 注解即可。代码如下
SpringBootApplication
public class Application implements CommandLineRunner {private Logger logger LoggerFactory.getLogger(Application.class);Autowiredprivate DataSource dataSource;public static void main(String[] args) {// 启动 Spring Boot 应用SpringApplication.run(Application.class, args);}Overridepublic void run(String... args) {try (Connection conn dataSource.getConnection()) {// 这里可以做点什么logger.info([run][获得连接{}], conn);} catch (SQLException e) {throw new RuntimeException(e);}}}
通过实现 CommandLineRunner 接口应用启动完成后回调 #run(String... args) 方法输出下 Connection 信息。执行日志如下
2019-11-12 11:15:32.303 INFO 41198 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-11-12 11:15:32.472 INFO 41198 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-11-12 11:15:32.473 INFO 41198 --- [ main] c.i.s.lab19.datasourcepool.Application : [run][获得连接HikariProxyConnection1561745898 wrapping com.mysql.jdbc.JDBC4Connection793138bd]可以看到HikariDataSource 成功初始化
3. HikariCP 多数据源 示例代码对应仓库lab-19-datasource-pool-hikaricp-multiple 。 在本小节我们会使用配置两个数据源的 HikariCP 连接池。 3.1 引入依赖 和 「2.1 引入依赖」 是一致。 3.2 应用配置文件 在 application.yml 中添加 HikariCP 配置如下 spring:# datasource 数据源配置内容datasource:# 订单数据源配置orders:url: jdbc:mysql://127.0.0.1:3306/test_orders?useSSLfalseuseUnicodetruecharacterEncodingUTF-8driver-class-name: com.mysql.jdbc.Driverusername: rootpassword:# HikariCP 自定义配置对应 HikariConfig 配置属性类hikari:minimum-idle: 20 # 池中维护的最小空闲连接数默认为 10 个。maximum-pool-size: 20 # 池中最大连接数包括闲置和使用中的连接默认为 10 个。# 用户数据源配置users:url: jdbc:mysql://127.0.0.1:3306/test_users?useSSLfalseuseUnicodetruecharacterEncodingUTF-8driver-class-name: com.mysql.jdbc.Driverusername: rootpassword:# HikariCP 自定义配置对应 HikariConfig 配置属性类hikari:minimum-idle: 15 # 池中维护的最小空闲连接数默认为 10 个。maximum-pool-size: 15 # 池中最大连接数包括闲置和使用中的连接默认为 10 个。 我们在 spring.datasource 配置项下定义了 orders 和 users 两个数据源的配置。而每个数据源的配置和我们在 「2.2 应用配置文件」 是一致的。3.3 数据源配置类 3.3.1 错误的示例 在网上我们会看到这样配置多个数据源的配置类。代码如下
Bean(name ordersDataSource)
ConfigurationProperties(prefix spring.datasource.orders)
public DataSource ordersDataSource() {return DataSourceBuilder.create().build();
}Bean(name usersDataSource)
ConfigurationProperties(prefix spring.datasource.users)
public DataSource ordersDataSource() {return DataSourceBuilder.create().build();
}
实际上这样做的话在部分场景下会存在问题这是为什么呢我们先来理解这段程序的用途。以 #ordersDataSource() 方法为例子 DataSourceBuilder.create().build() 代码段会创建一个 DataSource 数据源。搭配上 Bean(name ordersDataSource) 注解会创建一个名字为 ordersDataSource 的 DataSource Bean 。这里我们使用 HikariCP 所以返回的是 HikariDataSource Bean 。ConfigurationProperties(prefix spring.datasource.orders) 注解会将 spring.datasource.orders 配置项逐个属性赋值给 DataSource Bean 。看起来貌似没问题但是如果每个数据源如果有 HikariCP 的 hikari 自定义配置项时它的自定义配置项无法设置到 HikariDataSource Bean 中。因为spring.datasource.orders.hikari 是 spring.datasource.orders 的第二层属性。而 HikariDataSource 的配置属性在第一层这就导致无法正确的设置。
虽然存在该问题但是大多数项目我们并不会自定义 HikariCP 的 hikari 配置项所以这个问题就偷偷藏起来**“不存在”**了。 3.3.2 正确的示例
当然作为入门的示例艿艿还是希望提供正确的做法。
在 cn.iocoder.springboot.lab19.datasourcepool.config 包路径下我们会创建 DataSourceConfig 配置类。代码如下
// DataSourceConfig.javaConfiguration
public class DataSourceConfig {/*** 创建 orders 数据源的配置对象*/PrimaryBean(name ordersDataSourceProperties)ConfigurationProperties(prefix spring.datasource.orders) // 读取 spring.datasource.orders 配置到 DataSourceProperties 对象public DataSourceProperties ordersDataSourceProperties() {return new DataSourceProperties();}/*** 创建 orders 数据源*/Bean(name ordersDataSource)ConfigurationProperties(prefix spring.datasource.orders.hikari) // 读取 spring.datasource.orders 配置到 HikariDataSource 对象public DataSource ordersDataSource() {// 1.1 获得 DataSourceProperties 对象DataSourceProperties properties this.ordersDataSourceProperties();// 1.2 创建 HikariDataSource 对象return createHikariDataSource(properties);}/*** 创建 users 数据源的配置对象*/Bean(name usersDataSourceProperties)ConfigurationProperties(prefix spring.datasource.users) // 读取 spring.datasource.users 配置到 DataSourceProperties 对象public DataSourceProperties usersDataSourceProperties() {return new DataSourceProperties();}/*** 创建 users 数据源*/Bean(name usersDataSource)ConfigurationProperties(prefix spring.datasource.users.hikari)public DataSource usersDataSource() {// 获得 DataSourceProperties 对象DataSourceProperties properties this.usersDataSourceProperties();// 创建 HikariDataSource 对象return createHikariDataSource(properties);}private static HikariDataSource createHikariDataSource(DataSourceProperties properties) {// 创建 HikariDataSource 对象HikariDataSource dataSource properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();// 设置线程池名if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}}
这块代码我们是参考 Spring Boot DataSourceConfiguration.Hikari 配置类来实现的。#ordersDataSourceProperties() 方法创建 orders 数据源的 DataSourceProperties 配置对象。 Primary 注解保证项目中有一个主的 DataSourceProperties Bean 。new DataSourceProperties() 代码段会创建一个 DataSourceProperties 数据源的配置对象。搭配上 Bean(name ordersDataSourceProperties) 注解会创建一个名字为 ordersDataSourceProperties 的 DataSourceProperties Bean 。ConfigurationProperties(prefix spring.datasource.orders) 注解会将 spring.datasource.orders 配置项逐个属性赋值给 DataSourceProperties Bean 。#ordersDataSource() 方法创建 orders 数据源。 1.1 处调用 #ordersDataSourceProperties() 方法获得 orders 数据源的 DataSourceProperties 。1.2 处调用 #createHikariDataSource(DataSourceProperties properties) 方法创建 HikariDataSource 对象。这样spring.datasource.orders 配置项逐个属性赋值给 HikariDataSource Bean 。搭配上 Bean(name ordersDataSource) 注解会创建一个名字为 ordersDataSource 的 HikariDataSource Bean 。ConfigurationProperties(prefix spring.datasource.orders.hikari) 注解会将 HikariCP 的 spring.datasource.orders.hikari 自定义配置项逐个属性赋值给 HikariDataSource Bean 。users 数据源的配置同上就不重复解释了。
3.4 Application
创建 Application.java 类配置 SpringBootApplication 注解即可。代码如下
SpringBootApplication
public class Application implements CommandLineRunner {private Logger logger LoggerFactory.getLogger(Application.class);Resource(name ordersDataSource)private DataSource ordersDataSource;Resource(name usersDataSource)private DataSource usersDataSource;public static void main(String[] args) {// 启动 Spring Boot 应用SpringApplication.run(Application.class, args);}Overridepublic void run(String... args) {// orders 数据源try (Connection conn ordersDataSource.getConnection()) {// 这里可以做点什么logger.info([run][ordersDataSource 获得连接{}], conn);} catch (SQLException e) {throw new RuntimeException(e);}// users 数据源try (Connection conn usersDataSource.getConnection()) {// 这里可以做点什么logger.info([run][usersDataSource 获得连接{}], conn);} catch (SQLException e) {throw new RuntimeException(e);}}} 执行日志如下
2019-11-12 15:30:35.060 INFO 45868 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-11-12 15:30:35.365 INFO 45868 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-11-12 15:30:35.367 INFO 45868 --- [ main] c.i.s.lab19.datasourcepool.Application : [run][ordersDataSource 获得连接HikariProxyConnection1041547629 wrapping com.mysql.jdbc.JDBC4Connection3c989952]
2019-11-12 15:30:35.371 INFO 45868 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting...
2019-11-12 15:30:35.376 INFO 45868 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed.
2019-11-12 15:30:35.376 INFO 45868 --- [ main] c.i.s.lab19.datasourcepool.Application : [run][usersDataSource 获得连接HikariProxyConnection795748540 wrapping com.mysql.jdbc.JDBC4Connection7c098bb3]可以看到两个 HikariDataSource 成功初始化。