vibur-dbcp 是一个并发、快速和功能齐全的 JDBC 连接池,提供先进的性能监控功能。本文主要介绍 vibur-dbcp 的基本使用,文中使用到的软件版本:Java 1.8.0_191、vibur-dbcp 25.0、Spring Boot 2.3.12.RELEASE。

1、配置参数

1.1、连接池大小及公平性配置

参数

类型

默认值

描述

 poolInitialSize

int

 5

 初始连接数

 poolMaxSize

int

 50

 最大连接数

 poolFair

boolean

 true

 如果为 true,保证线程按照先进先出的次序还获取连接

 poolEnableConnectionTracking

boolean

 false

 如果为 true,连接池会记录每个借出连接的堆栈信息

 name

String

 "p" + auto-generated id

 连接池名称

1.2、基础配置

参数

类型

默认值

描述

driver

Driver

null


jdbc 的驱动;vibus 寻找驱动的次序:
1.driver 参数
2.driverClassName 参数
3.通过 jdbcUrl 来确定驱动


driverProperties

Properties

null

驱动的参数,将被用来调用 Driver.connect() 方法

driverClassName

String

null

驱动名称

jdbcUrl

String


jdbc 连接 url

username

String


用户名

password

String


密码

externalDataSource

DataSource

null

外部数据源,如果设置了将从该数据源获取连接

allowConnectionAfterTermination

boolean

false

连接池中断后是否允许获取连接

allowUnwrapping

boolean

true

是否允许获取 jdbc 的底层对象

1.3、连接超时及重试

参数

类型

默认值

描述

 connectionTimeoutInMs

 long

 15000

获取连接(DataSource.getConnection())的超时时间;0 表示无限制

 loginTimeoutInSeconds

 int

 5

 创建连接的超时时间,该值将用于调用 DriverManager.setLoginTimeout() 方法

 acquireRetryDelayInMs

long

500 

 创建连接失败时,等待重试的时间

 acquireRetryAttempt

 int

 创建连接失败时,最大重试次数

1.4、连接校验

参数

类型

默认值

描述

connectionIdleLimitInSeconds 

 int

5

 从连接池获取连接时,如果获取的连接空闲时间超过该设置,将对该连接进行校验。0 表示获取连接时每次都校验, 负数表示永远不校验。

 validateTimeoutInSeconds

 int

3

 获取连接时执行 testConnectionQuery 的超时时间,或创建连接 执行 initSQL 的超时时间。

 testConnectionQuery

String

isValid

 校验连接的查询语句,如果不设置则使用 Connection.isValid(int) 来校验连接;如果驱动支持 JDBC 4,强烈建议使用默认值,这会使得校验变得高效。

 initSQL

String

null

 连接第一次创建时执行的查询语句;isValid 表示将执行 Connection.isValid(int) 方法。

useNetworkTimeout

boolean 

false

如果为 true,在 testConnectionQuery 或 initSQL 启用且不为 isValid 的情况下,在执行 testConnectionQuery 或 initSQL 时,将调用 Connection.setNetworkTimeout() 方法;需要保证驱动支持 Connection.setNetworkTimeout() 方法。

networkTimeoutExecutor

Executor

null

useNetworkTimeout 启用时,执行 Connection.setNetworkTimeout(Executor executor, int milliseconds) 方法需要的 executor 对象。

1.5、查询慢及大结果集日志设置

参数

类型

默认值

描述

logQueryExecutionLongerThanMs

long

3000

对于长时间查询的语句是否记录日志;正数表示 SQL 语句的查询时间大于等于该设置时记录日志,0 表示总是记录,负数表示不记录

logStackTraceForLongQueryExecution

boolean

false

如果为 true,在 logQueryExecutionLongerThanMs 启用并记录日志时,同时记录 SQL 语句的堆栈信息。

logLargeResultSet

long

500

对于大结果集是否记录日志;正数表示如果从结果集中获取的结果条数(ResultSet.next() 的执行次数)超过该设置,记录日志;负数表示不记录。

logStackTraceForLargeResultSet

boolean

false

如果为 true,在 logLargeResultSet 启用并记录日志时,同时记录 SQL 语句的堆栈信息。

includeQueryParameters

boolean

true 

是否收集查询 SQL 的参数信息

1.6、获取连接慢及超时日志设置

参数

类型

默认值

描述

logConnectionLongerThanMs

long

3000

获取连接(DataSource.getConnection())的时间如果超过该设置,将记录日志;0 表示总是记录日志;负数表示不记录;如果 logConnectionLongerThanMs 大于 connectionTimeoutInMs,logConnectionLongerThanMs 将被设置为 connectionTimeoutInMs 的值。

logStackTraceForLongConnection

boolean

false

如果为 true,在 logConnectionLongerThanMs 启动并记录日志时,同时记录获取连接的堆栈信息。

logTakenConnectionsOnTimeout

boolean

false

从连接池获取连接超时,是否打印日志;如果为 true,超时了会大于所有借出连接的状态信息及堆栈信息。日志的格式可通过 takenConnectionsFormatter 设置。

logAllStackTracesOnTimeout

boolean

false

如果为 true,在 logTakenConnectionsOnTimeout 启用并记录日志时,同时记录其他所有没有获取连接的线程的堆栈信息

logLineRegex

Pattern

null

记录堆栈信息时(依据如下参数:logStackTraceForLongConnection, logStackTraceForLargeResultSet, logStackTraceForLongQueryExecution, logTakenConnectionsOnTimeout, logAllStackTracesOnTimeout),只记录符合正则表达式的信息。null 表示记录完整的堆栈信息。

takenConnectionsFormatter

TakenConnectionsFormatter

TakenConnectionsFormatter.Default

logTakenConnectionsOnTimeout 启用并记录日志时,可通过该参数设置日志的格式。

1.7、回调函数

回调函数只能在配置阶段设置,且启动后不能修改。

函数

类型

默认值

描述

viburDS.getConnHooks().addOnInit(...)

Hook.InitConnection

null

连接初始化后执行的函数

viburDS.getConnHooks().addOnGet(...)

Hook.GetConnection

null

从连接池获取连接后执行的函数

viburDS.getConnHooks().addOnClose(...)

Hook.CloseConnection

null

连接返回连接池前执行的函数

viburDS.getConnHooks().addOnDestroy(...)

Hook.DestroyConnection

null

原始连接关闭后执行的函数

viburDS.getConnHooks().addOnTimeout(...)

Hook.GetConnectionTimeout

null

在 logTakenConnectionsOnTimeout 启用并记录后执行的函数

viburDS.getInvocationHooks().addOnMethodInvocation(...)

Hook.MethodInvocation

null

在执行 JDBC 接口方法前,执行该函数;继承 Object 的方法、有关 close 的方法、java.sql.Wrapper 执行时不执行该函数。

viburDS.getInvocationHooks().addOnStatementExecution(...)

Hook.StatementExecution

null

在 JDBC Statement 执行时,该函数将包裹(around) Statement 的执行。

viburDS.getInvocationHooks().addOnResultSetRetrieval(...)

Hook.ResultSetRetrieval

null

在结果集关闭后执行该方法。

1.8、连接默认行为设置

参数

类型

默认值

描述

clearSQLWarnings

boolean

false

如果为 true,在连接返回连接池前,会清除 SQL 警告。

resetDefaultsAfterUse

boolean

false

如果为 true,在连接返回连接池后,重置该连接。

defaultAutoCommit

boolean

Driver's default

默认是否自动提交

defaultReadOnly

boolean

Driver's default

默认是否只读

defaultTransactionIsolation

String

Driver's default

默认的隔离级别

defaultCatalog

String

Driver's default

默认的 catalog

1.9、Statement 缓存设置

参数

类型

默认值

描述

statementCacheMaxSize

int

0

statement 缓存的最大数量;0 表示不启用 statement 缓存,最大不超过 2000。

1.10、连接池缩小设置

参数

类型

默认值

描述

poolReducerClass

String

org.vibur.dbcp.pool.PoolReducer

管理连接池缩小的类

reducerTimeIntervalInSeconds

int

30

连接池中的空闲连接多长时间后,空闲连接的数量将被减少

reducerSamples

int

15

在 reducerTimeIntervalInSeconds 时间内,poolReducer 多长时间醒来以统计连接池的信息。

1.11、严重 SQL 状态

参数

类型

默认值

描述

criticalSQLStates

String

08001,08006,08007,08S01,57P01,57P02,57P03,JZ0C0,JZ0C1

如果一个 SQL 异常出现在该设置里,将会失效所有的连接并关闭连接池。

1.12、启用 JMX

参数

类型

默认值

描述

enableJMX

boolean

true

是否开启 JMX

详细说明可参考官网文档:http://www.vibur.org/

2、使用

2.1、直接使用

2.1.1、引入依赖


<dependency>
<groupId>org.vibur</groupId>
<artifactId>vibur-dbcp</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
<version>1.4.2</version>
</dependency>


2.1.2、使用例子


package com.abc.demo.general.dbpool;

import org.vibur.dbcp.ViburDBCPDataSource;

import java.sql.*;

public class ViburDbcpCase {
public static void main(String[] args) {
ViburDBCPDataSource viburDBCPDataSource = new ViburDBCPDataSource();
viburDBCPDataSource.setName("vibur-dbcp连接池");
viburDBCPDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
viburDBCPDataSource.setJdbcUrl("jdbc:mysql://10.40.9.11:3306/mydb?useUnicode=true&characterEncoding=UTF-8");
viburDBCPDataSource.setUsername("root");
viburDBCPDataSource.setPassword("123456");
viburDBCPDataSource.setPoolInitialSize(2);
viburDBCPDataSource.setPoolMaxSize(10);
viburDBCPDataSource.setConnectionIdleLimitInSeconds(30);
viburDBCPDataSource.setTestConnectionQuery("select 1");
viburDBCPDataSource.setLogQueryExecutionLongerThanMs(5000);
viburDBCPDataSource.setLogStackTraceForLongQueryExecution(true);
viburDBCPDataSource.setStatementCacheMaxSize(200);
viburDBCPDataSource.start();

Connection connection = null;
try {
connection = viburDBCPDataSource.getConnection();
Statement st = connection.createStatement();
ResultSet rs = st.executeQuery("select version()");
if (rs.next()) {
System.out.println(rs.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(connection);
}

//实际使用中一般是在应用启动时初始化数据源,应用从数据源中获取连接;并不会关闭数据源。
viburDBCPDataSource.close();
}

private static void close(Connection connection) {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}


2.2、在 SpringBoot 中使用

2.1.1、引入依赖


<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath />
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>

<dependency>
<groupId>org.vibur</groupId>
<artifactId>vibur-dbcp</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
<version>1.4.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>


2.1.2、单数据源

application.yml 配置:


spring:
datasource:
vibur:
name: vibur-dbcp连接池
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://10.110.74.187:3306/egmp?useUnicode=true&characterEncoding=UTF-8
username: root
password: InsYR0ot187!
pool-initial-size: 2
pool-max-size: 10
connection-idle-limit-in-seconds: 30
test-connection-query: select 1
log-query-execution-longer-than-ms: 5000
log-stack-trace-for-long-query-execution: true
statement-cache-max-size: 200


数据源配置类:


package com.abc.demo.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.vibur.dbcp.ViburDBCPDataSource;


@Configuration
public class DataSourceConfig {
@Bean(name = "dataSource", initMethod = "start")
@ConfigurationProperties(prefix = "spring.datasource.vibur")
public ViburDBCPDataSource dataSource() {
ViburDBCPDataSource dataSource = DataSourceBuilder.create().type(ViburDBCPDataSource.class).build();
return dataSource;
}
}


使用:


@Autowired
private DataSource dataSource;


2.1.3、多数据源

application.yml 配置:


spring:
datasource:
vibur:
db1:
name: vibur-dbcp连接池1
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://10.110.74.187:3306/egmp?useUnicode=true&characterEncoding=UTF-8
username: root
password: InsYR0ot187!
pool-initial-size: 2
pool-max-size: 10
connection-idle-limit-in-seconds: 30
test-connection-query: select 1
log-query-execution-longer-than-ms: 5000
log-stack-trace-for-long-query-execution: true
statement-cache-max-size: 200
db2:
name: vibur-dbcp连接池2
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://10.110.74.187:3306/egmp?useUnicode=true&characterEncoding=UTF-8
username: root
password: InsYR0ot187!
pool-initial-size: 2
pool-max-size: 10
connection-idle-limit-in-seconds: 30
test-connection-query: select 1
log-query-execution-longer-than-ms: 5000
log-stack-trace-for-long-query-execution: true
statement-cache-max-size: 200


数据源配置类:


package com.abc.demo.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.vibur.dbcp.ViburDBCPDataSource;


@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "dataSource1", initMethod = "start")
@ConfigurationProperties("spring.datasource.vibur.db1")
public ViburDBCPDataSource dataSourceOne(){
return DataSourceBuilder.create().type(ViburDBCPDataSource.class).build();
}

@Bean(name = "dataSource2", initMethod = "start")
@ConfigurationProperties("spring.datasource.vibur.db2")
public ViburDBCPDataSource dataSourceTwo(){
return DataSourceBuilder.create().type(ViburDBCPDataSource.class).build();
}
}


使用:


@Autowired
@Qualifier("dataSource1")
private DataSource dataSource1;

@Autowired
@Qualifier("dataSource2")
private DataSource dataSource2;