Spring Boot - Spring Boot 数据库连接池 Hikari 介绍

发布时间 2023-04-18 09:03:32作者: Helios_Fz

Spring Boot 数据库连接池 Hikari 介绍

介绍

The HikariCP design aesthetic is Minimalism. 
In keeping with the simple is better or less is more design philosophy,
some configuration axis are intentionally left out.

HikariCP 奉行极简主义的设计美学。为了保持“越简单越好”和“少就是多”的设计理念,故意省略了一些配置。

使用

引入依赖

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.0</version>
</dependency>

初始化

方法一

HikariConfig config = new HikariConfig();
config.setJdbcUrl("");
config.setUsername("");
config.setPassword("");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
​
HikariDataSource ds = new HikariDataSource(config);

方法二

HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("");
ds.setUsername("");
ds.setPassword("");
...

方法三

HikariConfig config = new HikariConfig("/xxx/hikari.properties");
HikariDataSource ds = new HikariDataSource(config);
// properties file
dataSourceClassName=org.postgresql.ds.PGSimpleDataSource
dataSource.user=
dataSource.password=
dataSource.databaseName=
dataSource.portNumber=
dataSource.serverName=

方法四

Properties props = new Properties();
props.setProperty("dataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
props.setProperty("dataSource.user", "");
props.setProperty("dataSource.password", "");
props.setProperty("dataSource.databaseName", "");
​
HikariConfig config = new HikariConfig(props);
HikariDataSource ds = new HikariDataSource(config);

参数解释

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost/database?useUnicode=true&characterEncoding=utf8
    username: root
    password: root
    hikari:
        minimum-idle: 10
        idle-timeout: 30000
        maximum-pool-size: 20
        max-lifetime: 120000
        connection-timeout: 30000

以 Hikari 开头的配置都是可选配置,有默认值,不做显示配置也可以

autoCommit:默认是 true,自动提交从池中返回的连接。

connectionTimeout:等待来自池的连接的最大毫秒数,默认为 30000 ms = 30 s,允许最小时间是 250 毫秒,如果小于 250 毫秒,则被重置回 30 秒。

idleTimeout:连接允许在池中闲置的最长时间,默认为 600000,即 10 分钟。如果 idleTimeout + 1 秒 > maxLifetime 且 maxLifetime > 0,则会被重置为 0(代表永远不会退出);如果 idleTimeout != 0 且小于 10 秒,则会被重置为 10 秒。只有当 minimumIdle 小于 maximumPoolSize 时,这个参数才生效,当空闲连接数超过 minimumIdle,而且空闲时间超过 idleTimeout,则会被移除。

keepaliveTime:连接存活时间,这个值必须小于 maxLifetime 值。keepalive "只会发生在空闲的连接上。当对一个给定的连接进行 "keepalive"的时间到了,该连接将从池中移除。允许的最小值是 30000 ms(30秒),但最理想的值是在分钟范围内。默认值:0

maxLifetime:池中连接最长生命周期。默认为 1800000,如果不等于 0 且小于 30 秒则会被重置回 30 分钟。

minimumIdle:控制连接池空闲连接的最小数量,当连接池空闲连接少于 minimumIdle,而且总共连接数不大于 maximumPoolSize 时,HikariCP 会尽力补充新的连接。为了性能考虑,不建议设置此值,而是让 HikariCP 把连接池当做固定大小的处理,默认 minimumIdle 与 maximumPoolSize 一样。当 minIdle < 0 或者 minIdle > maxPoolSize,则被重置为 maxPoolSize,该值默认为 10。

maximumPoolSize:池中最大连接数,包括闲置和使用中的连接。默认为 10。如果 maxPoolSize 小于1,则会被重置。当 minIdle <=0 被重置为DEFAULT_POOL_SIZE 则为 10;如果 minIdle > 0 则重置为 minIdle 的值。

poolName:连接池的用户定义名称,主要出现在日志记录和 JMX 管理控制台中以识别池和池配置。默认为 HikariPool-1。

readOnly:从池中获取的连接是否默认处于只读模式。默认为 false。这个属性工作与否取决于数据库的实现。

connectionTestQuery:如果你的驱动程序支持 JDBC4,我们强烈建议不要设置这个属性。这是针对不支持 JDBC4 Connection.isValid() API的 "传统 "驱动程序。这是一个查询,在一个连接从池子里给你之前会被执行,以验证与数据库的连接是否仍然有效。同样,尝试在没有这个属性的情况下运行数据库池,如果你的驱动不符合JDBC4标准,HikariCP 会记录一个错误。默认值:无。

问题

描述

在生产环境中使用 HikariCP 遇到了如下问题:

  • 系统运行一段时间后,应用会报告无法连接数据库库。异常信息:HikariPool-1 - Connection is not available,request timed out after 1954466ms.
  • 每隔一个小时左右,会有如下日志:HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=54s566ms151µs86ns)
  • 系统经历一次高并发请求之后,服务器CPU保持在 90% 降不下来

解决

在启动服务时,发现连接池启动的时候,总报一个提示:

HikariPool-1 - Driver does not support get/set network timeout for connections. (oracle.jdbc.driver.T4CConnection.getNetworkTimeout()I)

经调查发现,数据版本是Oracle 12.2,但服务的 ojdbc 版本是6,更新为 ojdbc8 之后就解决了这个问题。

附 Oracle、JDK、ojdbc驱动版本的对应关系

Oracle Database Version Release-Specific JDBC JAR File with Supported JDK
21.x ojdbc11.jar with JDK 11, JDK 12, JDK 13, JDK 14 and JDK 15
ojdbc8.jar with JDK 8, JDK 11, JDK 12, JDK 13, JDK 14 and JDK 15
19.x ojdbc10.jar with JDK 10, JDK 11
ojdbc8.jar with JDK 8, JDK 9, JDK 11
18.3 ojdbc8.jar with JDK 8, JDK 9, JDK 10, JDK 11
12.2 or 12cR2 ojdbc8.jar with JDK 8
12.1 or 12cR1 ojdbc7.jar with JDK 7, JDK 8
ojdbc6.jar with JDK 6
11.2 or 11gR2 ojdbc6.jar with JDK 6, JDK 7, JDK 8
ojdbc5.jar with JDK 5