1. 项目概述
Druid作为阿里巴巴开源的数据库连接池实现,在Java生态中占据着重要地位。我在实际项目中使用Druid已有五年多时间,从早期的Spring Boot 1.x到现在的Spring Boot 3.x版本,见证了它在性能监控、SQL防注入等方面的持续进化。本文将基于Spring Boot 3环境,分享Druid连接池的核心配置技巧和实战经验。
相比HikariCP等其他连接池,Druid的最大优势在于其强大的监控功能。通过内置的StatViewServlet和WebStatFilter,我们可以实时监控SQL执行情况、连接池状态等关键指标。在最近的一个电商项目中,正是依靠Druid的监控数据,我们及时发现并解决了慢SQL导致的连接泄漏问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心配置解析
2.1 基础依赖引入
在Spring Boot 3项目中,首先需要在pom.xml中添加Druid的starter依赖:
xml复制<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.18</version>
</dependency>
这里特别需要注意版本号的选择。Spring Boot 3对JDK17+有强制要求,因此必须使用适配Spring Boot 3的starter。我在升级项目时就曾因为使用了旧版starter导致兼容性问题,花费了大量时间排查。
2.2 YAML配置详解
完整的application.yml配置示例如下:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
filters: stat,wall
web-stat-filter:
enabled: true
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: admin
关键参数说明:
- initial-size:初始化连接数,建议设置为与min-idle相同
- max-active:最大连接数,需要根据数据库性能和业务压力调整
- time-between-eviction-runs-millis:连接空闲检查间隔
- filters:启用stat(监控统计)和wall(SQL防火墙)
重要提示:生产环境务必修改stat-view-servlet的登录账号密码,我曾遇到过因为使用默认密码导致的安全事故
2.3 监控界面配置
Druid的监控界面是其一大特色,通过以下配置可以启用:
java复制@Configuration
public class DruidConfig {
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean =
new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
bean.addInitParameter("loginUsername", "admin");
bean.addInitParameter("loginPassword", "admin123");
bean.addInitParameter("resetEnable", "false");
return bean;
}
@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter() {
FilterRegistrationBean<WebStatFilter> bean =
new FilterRegistrationBean<>(new WebStatFilter());
bean.addUrlPatterns("/*");
bean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.css,/druid/*");
return bean;
}
}
监控界面主要功能包括:
- 数据源:查看连接池基本状态
- SQL监控:记录所有执行的SQL及其耗时
- SQL防火墙:防御SQL注入攻击
- Web应用:统计URI请求情况
3. 高级功能实现
3.1 多数据源配置
在实际项目中,我们经常需要配置多个数据源。以下是基于Druid的多数据源配置方案:
java复制@Configuration
@MapperScan(basePackages = "com.example.mapper.primary",
sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class PrimaryDataSourceConfig {
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.primary")
public DataSource primaryDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "primarySqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/primary/*.xml"));
return bean.getObject();
}
@Bean(name = "primarySqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory(dataSource));
}
}
对应的YAML配置:
yaml复制spring:
datasource:
druid:
primary:
url: jdbc:mysql://localhost:3306/primary
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
3.2 SQL防注入配置
Druid内置了强大的SQL防火墙功能,可以通过以下方式配置:
yaml复制spring:
datasource:
druid:
filter:
wall:
enabled: true
config:
drop-table-allow: false
alter-table-allow: false
none-base-statement-allow: false
multi-statement-allow: true
我曾经在一个金融项目中,通过分析Druid的WallFilter日志,成功拦截了多次SQL注入攻击尝试。这些攻击尝试包括常见的'OR 1=1--等注入手法。
3.3 慢SQL监控
慢SQL是影响系统性能的常见问题,Druid可以方便地监控慢SQL:
yaml复制spring:
datasource:
druid:
filter:
stat:
enabled: true
slow-sql-millis: 1000
log-slow-sql: true
当SQL执行时间超过slow-sql-millis设置的值时,Druid会记录该SQL并在监控界面标记为慢SQL。在我的经验中,合理设置这个阈值非常重要,通常生产环境建议设置为300-500ms。
4. 性能调优实战
4.1 连接池参数优化
连接池参数的合理配置对系统性能影响巨大。以下是我总结的调优经验:
| 参数名 | 默认值 | 建议值 | 说明 |
|---|---|---|---|
| initialSize | 0 | 与minIdle相同 | 避免启动时频繁创建连接 |
| maxActive | 8 | 20-100 | 根据并发量和DB性能调整 |
| minIdle | 0 | 与initialSize相同 | 保持最小空闲连接 |
| maxWait | -1 | 5000 | 避免线程长时间等待 |
| timeBetweenEvictionRunsMillis | 60000 | 30000 | 连接回收检查间隔 |
| minEvictableIdleTimeMillis | 1800000 | 600000 | 连接最大空闲时间 |
在最近的一个高并发项目中,我们将maxActive从默认的8调整到50后,系统吞吐量提升了近3倍。
4.2 监控数据解读
Druid监控界面提供了丰富的数据指标,关键指标包括:
- 活跃连接数(ActiveCount):当前正在使用的连接数
- 空闲连接数(IdleCount):当前可用的连接数
- 等待线程数(WaitThreadCount):等待获取连接的线程数
- 执行次数(ExecuteCount):SQL执行总次数
- 执行时间(ExecuteTimeMillis):SQL执行总耗时
健康状态的连接池应该满足:
- ActiveCount < maxActive
- WaitThreadCount接近0
- ExecuteTimeMillis/ExecuteCount < 慢SQL阈值
4.3 常见问题排查
连接泄漏问题
症状:ActiveCount持续增长不释放
解决方案:
- 检查是否忘记关闭Connection/Statement/ResultSet
- 配置removeAbandoned相关参数:
yaml复制spring:
datasource:
druid:
remove-abandoned: true
remove-abandoned-timeout: 300
log-abandoned: true
连接获取超时
症状:大量WaitThreadCount
解决方案:
- 适当增加maxActive
- 优化慢SQL
- 检查数据库负载
监控页面无法访问
可能原因:
- 未正确配置StatViewServlet
- 拦截器拦截了/druid/*路径
- 未添加@ServletComponentScan注解
5. 生产环境最佳实践
5.1 安全加固措施
- 修改默认账号密码:绝对不要使用admin/admin这样的默认凭证
- 限制访问IP:通过配置只允许内网IP访问监控界面
- 禁用重置功能:设置resetEnable为false
- 启用SSL:如果监控界面需要外网访问,必须配置HTTPS
java复制@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean =
new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
// 只允许192.168.1.100访问
bean.addInitParameter("allow", "192.168.1.100");
// 禁止通过界面重置所有数据
bean.addInitParameter("resetEnable", "false");
return bean;
}
5.2 监控告警集成
可以将Druid监控数据集成到Prometheus等监控系统中:
java复制@Bean
public DruidStatViewServlet druidStatViewServlet() {
DruidStatViewServlet druidStatViewServlet = new DruidStatViewServlet();
// 暴露metrics端点供Prometheus采集
ServletRegistrationBean<DruidStatViewServlet> servletRegistrationBean =
new ServletRegistrationBean<>(druidStatViewServlet, "/druid/*");
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "securePassword");
return servletRegistrationBean;
}
5.3 与Spring Boot Actuator集成
Spring Boot Actuator提供了健康检查端点,可以集成Druid的健康状态:
yaml复制management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: health,info,druid
这样可以通过/actuator/health端点检查数据库连接状态。
在实际部署中,我发现将Druid监控与现有监控系统集成可以大幅提高运维效率。例如,当连接池等待线程数超过阈值时自动触发告警,帮助我们在用户感知前发现问题。
6. 版本升级注意事项
从Spring Boot 2.x升级到3.x时,Druid配置有以下变化:
-
starter依赖变更:
- 旧版:druid-spring-boot-starter
- 新版:druid-spring-boot-3-starter
-
部分配置项废弃:
- spring.datasource.druid.stat-view-servlet.allow
- spring.datasource.druid.stat-view-servlet.deny
替换为spring.datasource.druid.stat-view-servlet.init-parameters
-
监控界面路径:
- 旧版可能配置为/druid/*
- 建议统一为/actuator/druid保持一致性
我在最近的项目升级过程中遇到的一个典型问题是:由于未及时更新starter依赖版本,导致监控界面无法正常显示。解决方法是确保使用1.2.18及以上版本的druid-spring-boot-3-starter。
