• Java 数据库连接池介绍(6)viburdbcp 介绍


    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;
  • 相关阅读:
    Safe Path(bfs+一维数组存图)
    一维树状数组入门
    Ancient Go(简单DFS)
    Sudoku(简单DFS)
    Strategic game(树形DP入门)
    多线程源码分析
    Navicat premium12的破解方法,无需注册码
    MySQL和Oracle的区别
    java Web项目中什么场景中会用到java多线程?
    TCP协议三次握手、四次断开 过程分析
  • 原文地址:https://www.cnblogs.com/wuyongyin/p/15538599.html
Copyright © 2020-2023  润新知