jdbc · 2021-12-25 0

数据库连接池druid配置

一、配置

配置 缺省值 说明
name 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分,如果没有配置,将会生成一个名字,格式是:"DataSource-"+System.identityHashCode(this)
url 连接数据库的url,不同数据库不一样。例如:mysql : jdbc:mysql://127.0.0.1:3306/druid_db
username 连接数据库的用户名
password 连接数据库的密码
driverClassName 根据url自动识别,可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName
initialSize 0 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
minIdle 0 最小连接数量
maxIdle 8 (已废弃),可使用maxActive
maxActive 8 最大连接数量
maxWait -1 从连接池中获取连接的最大等待时间,单位ms,默认-1,即会一直等待下去
timeBetweenEvictionRunsMillis 60*000 默认值60s,DestroyTask 执行间隔时间。检测需要关闭的空闲连接和长时间没关闭的连接
removeAbandoned false 处理活跃连接,针对连接泄漏问题。是否清除已经超过removeAbandonedTimeout设置的无效连接。建议值:true
logAbandoned false 用于连接泄漏场景,关闭abandonded连接时是否输出错误日志。建议值:true
removeAbandonedTimeoutMillis 300 * 1000 处理活跃连接(未关闭),针对连接泄漏、数据库死锁问题。超过时间限制,回收无用的连接,removeAbandoned 必须为 true。数据库连接的状态:关闭、未关闭(活跃)、在执行(这个值执行前后会设置)。还在执行的连接不会被回收
minEvictableIdleTimeMillis 30 * 60 * 1000 最小检查间隙,一个连接在池中最小生存的时间(结合检查区间来看,闲置时间超过这个时间,才会被丢弃),缺省值30min
maxEvictableIdleTimeMillis 7 * 60 * 60 * 1000 最大检查间隙,一个连接在池中最大生存的时间(无视检查区间,只要闲置时间超过这个时间,就一定会被丢弃),缺省值7h

说明maxIdle已经废弃,用maxActive和minIdle来表示数据库连接池的maxPoolSize和minPoolSize。

二、监控

maven依赖

<!-- mysql -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.15</version>
</dependency>

<!-- druid -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.2.8</version>
</dependency>

web.xml

  <servlet>
    <servlet-name>druidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>druidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
  </servlet-mapping>

三、使用

  • getActiveCount()方法返回了当前正在使用的连接数量,
  • getConnectCount()方法返回了曾经连上与已经连上的连接总数,
  • getPoolingCount()返回了连接池中剩余空闲的连接数量。

创建 DruidDataSource

public static void createDataSource(String name) {
    DruidDataSource dataSource = new DruidDataSource();

    if (name != null) {
        dataSource.setName(name);
    }

    String url = "jdbc:mysql://localhost:3306/druid_db?useUnicode=true&useSSL=false";
    String username = "root";
    String password = "123456";
    String driverClassName = "com.mysql.cj.jdbc.Driver";

    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    dataSource.setDriverClassName(driverClassName);

    // 初始化时建立物理连接的个数
    dataSource.setInitialSize(2);
    // 最小连接数量
    dataSource.setMinIdle(1);
    // 最大连接数量
    dataSource.setMaxActive(5);
    // 获取连接的最大等待时间
    dataSource.setMaxWait(2000);

    // 启用废弃连接回收功能(默认是 false)。连接泄漏监测。官方不建议在生产环境使用。
    // 可能因为程序问题,导致申请的 connect 在处理完 SQL 查询后,不能回到连接池的怀抱。那么这个 connect 处理游离态,
    // 它真实存在,但后续谁也申请不到它,这就是连接泄露。
    // 不是简单的过期强制回收
    // dataSource.setRemoveAbandoned(true);

    // 超过 5s(默认 300 s),强制回收连接。连接被认定为“废弃连接”的超时时间。如果你的应用程序主动持有连接而不释放,Druid 不会强行中断你的业务逻辑。
    // dataSource.setRemoveAbandonedTimeout(5);

    // 每 3s(默认 60s) 检查空闲连接的频率,空闲连接检查的间隔时间,
    // Druid 池中的 connect 数量是一个动态从 minIdle 到 maxActive 扩张与收缩的过程。
    dataSource.setTimeBetweenEvictionRunsMillis(3 * 1000);

    // 最小空闲时间,5s(默认 30 分钟),如果连接池中非运行中的连接数大于 minIdle ,并且某些连接的非运行时间大于 minEvictableIdleTimeMillis ,
    // 则连接池会将这部分连接设置成 Idle 状态并关闭。
    // 官方解释:一个连接在池中最小生存的时间(结合检查区间来看,闲置时间超过这个时间,才会被丢弃)。
    dataSource.setMinEvictableIdleTimeMillis(5 * 1000);

    // 最大空闲时间,10s(默认 7 小时)
    // 如果连接太久没用,数据库也会把它关闭(MySQL 默认 8 小时),这时如果连接池不把这条连接关闭,程序就会拿到一条已经被数据库关闭的连接。
    // 为了避免这种情况, Druid 会判断池中的连接状态。如果非运行时间大于 maxEvictableIdleTimeMillis ,也会强行把它关闭,
    // 而不用判断空闲连接数是否小于 minIdle 。
    // 官方解释:一个连接在池中最大生存的时间(无视检查区间,只要闲置时间超过这个时间,就一定会被丢弃)。
    dataSource.setMaxEvictableIdleTimeMillis(10 * 1000);

    // 为了不让慢查询占用整个连接池,而拖垮整个应用,我们设置查询超时时间 queryTimeout
    // dataSource.setQueryTimeout();

    try {
        dataSource.setFilters("stat");
    } catch (SQLException e) {
        e.printStackTrace();
    }
}