Druid连接池配置案例

wen java案例 2

本文目录导读:

Druid连接池配置案例

  1. 基础配置(纯Java或XML方式)
  2. 生产环境完整配置(JavaConfig方式)
  3. 注册监控页面(StatViewServlet 与 WebStatFilter)
  4. Spring Boot 集成配置
  5. Druid 常用配置参数详解(FAQ)
  6. 监控查看 SQL 示例
  7. 常见问题排查(注意事项)

Druid(阿里巴巴数据库连接池)是目前Java应用中最常用的数据库连接池之一,它不仅提供高效的连接管理,还内置了强大的监控防SQL注入功能。

以下分基础配置生产环境完整配置监控配置Spring Boot集成四个维度提供案例。


基础配置(纯Java或XML方式)

这是最核心的配置,演示了数据源的基本属性。

# jdbc.properties 文件
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
jdbc.username=root
jdbc.password=your_password
# 初始化连接数
jdbc.initialSize=5
# 最小空闲连接数
jdbc.minIdle=5
# 最大连接池数量
jdbc.maxActive=20
# 获取连接时最大等待时间(毫秒)
jdbc.maxWait=60000
# 间隔多久才进行一次检测(毫秒)
jdbc.timeBetweenEvictionRunsMillis=60000
# 连接保持空闲而不被驱逐的最长时间(毫秒)
jdbc.minEvictableIdleTimeMillis=300000
# 验证连接是否可用的SQL
jdbc.validationQuery=SELECT 1 FROM DUAL
# 申请连接时执行validationQuery检测连接是否有效
jdbc.testWhileIdle=true
# 申请连接时检测(建议false,影响性能)
jdbc.testOnBorrow=false
# 归还连接时检测(建议false)
jdbc.testOnReturn=false
# 是否缓存preparedStatement
jdbc.poolPreparedStatements=true

对应Java Bean 配置(Spring XML 示例):

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <!-- 连接池配置 -->
    <property name="initialSize" value="${jdbc.initialSize}" />
    <property name="minIdle" value="${jdbc.minIdle}" />
    <property name="maxActive" value="${jdbc.maxActive}" />
    <property name="maxWait" value="${jdbc.maxWait}" />
    <!-- 连接检测配置 -->
    <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
    <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
    <property name="validationQuery" value="${jdbc.validationQuery}" />
    <property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
    <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
    <property name="testOnReturn" value="${jdbc.testOnReturn}" />
    <!-- 预编译缓存 -->
    <property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}" />
    <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
</bean>

生产环境完整配置(JavaConfig方式)

在Spring项目中,推荐使用@Configuration类进行配置,便于管理。

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
@PropertySource("classpath:jdbc.properties")
public class DruidConfig {
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Bean(destroyMethod = "close")
    public DataSource dataSource() throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        // -------- 基础连接池配置 --------
        dataSource.setInitialSize(10);       // 初始化连接数
        dataSource.setMinIdle(10);           // 最小空闲连接数
        dataSource.setMaxActive(100);        // 最大活跃连接数
        // 获取连接等待超时时间(毫秒)
        dataSource.setMaxWait(60000);        
        // 连接在池中最小生存时间(毫秒)
        dataSource.setMinEvictableIdleTimeMillis(300000);
        // -------- 高级性能配置 --------
        // 开启PSCache(预编译缓存),显著提升Oracle、SQLServer性能
        dataSource.setPoolPreparedStatements(true);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(30);
        // 是否开启异步关闭连接(默认false),开启后可减少获取连接的阻塞时间
        dataSource.setAsyncCloseConnectionEnable(false);
        // -------- 连接保活与检测 --------
        // 验证查询语句(MySQL可用 SELECT 1,Oracle用 SELECT 1 FROM DUAL)
        dataSource.setValidationQuery("SELECT 1");
        dataSource.setTestWhileIdle(true);   // 空闲时检测(推荐开启)
        dataSource.setTestOnBorrow(false);   // 申请时检测(影响性能)
        dataSource.setTestOnReturn(false);   // 归还时检测
        // 每60秒运行一次空闲连接回收器
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        // 防止因网络闪断导致连接不可用(不主动关闭,而是验证)
        dataSource.setKeepAlive(true);
        dataSource.setKeepAliveBetweenTimeMillis(60000);
        // -------- 安全与监控(可选) --------
        // 设置连接出错自动重连
        dataSource.setBreakAfterAcquireFailure(false);
        dataSource.setConnectionErrorRetryAttempts(3);
        // 开启Druid的监控统计功能(StatFilter 和 WallFilter 防SQL注入)
        try {
            dataSource.setFilters("stat,wall"); 
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return dataSource;
    }
}

注册监控页面(StatViewServlet 与 WebStatFilter)

如果需要通过Web界面查看连接池状态、慢SQL等,需要在web.xml或Spring Boot中配置。

Servlet 3.0 注解方式(适用于普通Tomcat项目)

import com.alibaba.druid.support.http.StatViewServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
@WebServlet(urlPatterns = "/druid/*", 
    initParams = {
        @WebInitParam(name="allow", value="127.0.0.1"), // 允许访问的IP,留空表示所有
        @WebInitParam(name="deny", value=""),   // 拒绝访问的IP
        @WebInitParam(name="loginUsername", value="admin"), // 监控页面登录名
        @WebInitParam(name="loginPassword", value="admin123"), // 监控页面登录密码
        @WebInitParam(name="resetEnable", value="false") // 禁用HTML页面上的“Reset All”功能
    })
public class DruidStatViewServlet extends StatViewServlet {
    private static final long serialVersionUID = 1L;
}

配置 WebStatFilter(用于统计Web请求)

import com.alibaba.druid.support.http.WebStatFilter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(filterName="druidWebStatFilter", urlPatterns="/*",
    initParams={
        @WebInitParam(name="exclusions", value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"), // 忽略资源
        @WebInitParam(name="sessionStatEnable", value="true"), // 启用Session统计
        @WebInitParam(name="profileEnable", value="true")      // 启用URI监控
    })
public class DruidStatFilter extends WebStatFilter {
    private static final long serialVersionUID = 1L;
}

访问监控页面:http://your-server-ip:port/项目名/druid/index.html


Spring Boot 集成配置

在Spring Boot中,数据源配置通常在application.yml中进行,如果使用spring-boot-starter-jdbcmybatis,可以自动装配。

引入依赖(pom.xml)

<!-- Druid Spring Boot Starter -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.20</version>
</dependency>

application.yml 完整配置

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    # Druid 连接池专属配置
    druid:
      # 初始化连接数
      initial-size: 10
      # 最小空闲数
      min-idle: 10
      # 最大连接数
      max-active: 100
      # 获取连接超时时间
      max-wait: 60000
      # 间隔多久检测一次空闲连接(毫秒)
      time-between-eviction-runs-millis: 60000
      # 最小驱逐时间
      min-evictable-idle-time-millis: 300000
      # 验证SQL
      validation-query: SELECT 1
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      # 打开PSCache(预编译缓存)
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      # 配置监控统计拦截的filters(stat: 监控统计, wall: 防SQL注入, log4j2: 日志)
      filters: stat,wall,slf4j
      # 慢SQL记录(超过10秒)
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 启用内置监控页面(需要引入JSP支持或独立访问)
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        login-username: admin
        login-password: admin123
        reset-enable: false
        # 白名单(不配置则允许所有)
        allow: 127.0.0.1
        # 黑名单
        deny: 
      # Web监控过滤器
      web-stat-filter:
        enabled: true
        url-pattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
        session-stat-enable: true
        profile-enable: true

Druid 常用配置参数详解(FAQ)

参数名 默认值 说明 建议
initialSize 0 初始化时建立物理连接的个数,初始化发生在显示调用init方法,或第一次getConnection时 建议 >=5
maxActive 8 最大连接池数量,即允许的最大并发连接数 按业务并发量调整
maxWait -1 (无限) 获取连接时最大等待时间,单位毫秒,配置后若超时则抛异常 建议 5000~60000
minIdle 0 最小空闲连接数,低于该值时Druid会尝试补充 建议与initialSize相同
timeBetweenEvictionRunsMillis 60s 检测线程运行间隔,检测连接是否有效、是否需要关闭空闲连接 建议 60000
minEvictableIdleTimeMillis 30分钟 连接保持空闲而不被回收的最长时间 建议 30000-60000
validationQuery 验证连接生效的SQL,如 SELECT 1 必须配置
testWhileIdle true 申请连接时如果空闲时间大于timeBetween...则执行validationQuery检测 保持true
testOnBorrow true 申请连接时执行validationQuery检测连接是否有效 建议false(性能好)
testOnReturn false 归还连接时执行validationQuery检测连接是否有效 建议false
poolPreparedStatements false 是否缓存PreparedStatement,对于复用率高的SQL建议开启 建议true
maxPoolPreparedStatementPerConnectionSize -1 每个连接上PSCache的大小 建议 20-50
filters 配置扩展插件:stat(监控), wall(防火墙), slf4j(日志) 必配stat,wall

监控查看 SQL 示例

通过com.alibaba.druid.stat.DruidDataSourceStatManager可以查看连接池状态:

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.stat.DruidDataSourceStatManager;
// 获取所有数据源
Set<DruidDataSource> dataSources = DruidDataSourceStatManager.getDruidDataSourceInstances();
for (DruidDataSource dataSource : dataSources) {
    System.out.println("ActiveCount: " + dataSource.getActiveCount());
    System.out.println("PoolingCount: " + dataSource.getPoolingCount());
    System.out.println("ErrorCount: " + dataSource.getErrorCount());
    // 等等...
}

常见问题排查(注意事项)

  1. 连接池泄漏:建议配置removeAbandoned=trueremoveAbandonedTimeout=300(秒),自动回收超过5分钟未关闭的连接(注意:不要在生产环境轻易开启,这可能影响长事务)。
  2. 验证SQL:如果使用Oracle,validationQuery必须为SELECT 1 FROM DUAL
  3. 性能调优maxActive不是越大越好,过大可能导致数据库压力过大或频繁GC,建议压测后确定大小。
  4. 加密密码:数据库密码建议使用Druid的ConfigTools进行加密,在配置中加入publicKeypassword=${#...}的配置密文访问。

抱歉,评论功能暂时关闭!