1. 为什么选择Druid作为Spring Boot的数据源
在Java生态中,数据库连接池的选择直接影响着应用的性能和稳定性。Druid作为阿里巴巴开源的高性能数据库连接池,相比HikariCP、Tomcat JDBC等方案有几个独特优势:
- 监控能力内置:Druid自带的StatFilter能提供SQL执行监控、URI监控等关键指标,这是其他连接池需要额外集成才能实现的
- 防御性设计:支持SQL注入防护、配置加密等企业级特性
- Spring生态友好:与Spring Boot的自动配置机制深度适配,只需少量配置即可启用高级功能
实际项目中我们发现,当SQL执行时间超过100ms时,Druid的监控界面能快速定位到具体慢查询,而HikariCP需要额外集成Micrometer等组件才能实现类似功能。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础整合步骤详解
2.1 依赖配置
在pom.xml中添加以下依赖(Spring Boot 3.x版本):
xml复制<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.20</version>
</dependency>
对于Spring Boot 2.x用户应使用:
xml复制<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.20</version>
</dependency>
2.2 基础配置
application.yml中至少需要配置:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
3. 监控功能深度配置
3.1 启用监控控制台
在配置类中添加:
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", "admin");
return bean;
}
}
3.2 监控过滤器配置
java复制@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter() {
FilterRegistrationBean<WebStatFilter> bean =
new FilterRegistrationBean<>(new WebStatFilter());
bean.addUrlPatterns("/*");
bean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,/druid/*");
return bean;
}
4. 生产环境最佳实践
4.1 安全加固方案
在application.yml中添加:
yaml复制spring:
datasource:
druid:
stat-view-servlet:
enabled: true
login-username: ${DRUID_USERNAME:admin}
login-password: ${DRUID_PASSWORD:#{T(java.util.UUID).randomUUID().toString()}}
allow: 192.168.1.100,127.0.0.1
deny: 192.168.1.73
我们项目组曾发生过因未配置IP白名单导致监控界面被扫描工具发现的案例,建议至少设置loginPassword和环境变量绑定
4.2 性能调优参数
yaml复制spring:
datasource:
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 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
filters: stat,wall
5. 监控数据解读指南
Druid监控首页的几个关键指标:
- 活跃连接数:当前正在使用的连接数,持续接近max-active值说明需要扩容
- 执行次数:结合QPS监控可以判断SQL执行效率
- 执行时间分布:重点关注750ms以上的SQL
- 连接持有时间分布:正常应在毫秒级,秒级持有可能意味着事务未关闭
6. 常见问题排查
6.1 监控页面404问题
检查顺序:
- 确认依赖版本匹配Spring Boot主版本
- 检查是否有其他安全框架拦截了/druid/*路径
- 查看启动日志是否有"DruidStatViewServlet"注册成功的日志
6.2 SQL监控不显示
需要确保:
- 配置了filters: stat
- 没有使用@Transactional(readOnly = true)注解(会跳过监控)
- 检查是否配置了多个数据源但未指定主数据源
7. 进阶集成方案
7.1 与Spring Boot Admin集成
在admin客户端添加:
java复制@Bean
public DruidDataSourcePoolMetadata druidPoolMetadata(DataSource dataSource) {
return new DruidDataSourcePoolMetadata((DruidDataSource) dataSource);
}
7.2 Prometheus监控集成
添加依赖:
xml复制<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
配置类中添加:
java复制@Bean
public DruidStatMetrics druidStatMetrics(DataSource dataSource) {
return new DruidStatMetrics(dataSource);
}
8. 动态数据源场景下的特殊处理
使用dynamic-datasource-spring-boot-starter时,需要在每个数据源单独配置:
yaml复制spring:
datasource:
dynamic:
druid:
initial-size: 5
max-active: 20
filters: stat,wall
datasource:
master:
url: jdbc:mysql://localhost:3306/master
username: root
password: 123456
slave:
url: jdbc:mysql://localhost:3306/slave
username: root
password: 123456
9. 监控数据持久化方案
通过实现FilterEventAdapter可以将监控数据保存到数据库:
java复制public class MyStatLogger extends FilterEventAdapter {
@Override
protected void logExecuteSql(String sql) {
// 存入业务数据库
logRepository.save(new SqlLog(sql));
}
}
然后在配置中注册:
yaml复制spring:
datasource:
druid:
filters: stat,wall
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
db-type: mysql
10. 版本升级注意事项
从Spring Boot 2.x升级到3.x时:
- 必须更换starter为druid-spring-boot-3-starter
- 原配置项spring.datasource.druid迁移到spring.datasource.druid
- 监控页面的CSRF防护需要额外处理:
java复制@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth ->
auth.requestMatchers("/druid/**").permitAll());
return http.build();
}
在实际项目中,我们发现Druid的监控数据对定位凌晨3点的数据库连接泄漏问题起到了关键作用。通过分析连接持有时间分布图,最终定位到某个批处理任务未正确关闭连接。建议团队至少每周查看一次SQL监控面板,重点关注执行时间Top10的SQL语句。
