1. 为什么需要数据库连接池?
在Spring Boot应用开发中,数据库连接管理是个容易被忽视但极其重要的问题。每次执行SQL时都新建连接,会导致严重的性能问题。我曾在生产环境遇到过因为连接管理不当导致的数据库崩溃——应用启动后短短几分钟内,数据库连接数就突破了最大限制。
Druid作为阿里巴巴开源的数据库连接池,相比HikariCP等方案有几个独特优势:
- 监控功能完善:内置StatViewServlet和WebStatFilter,提供SQL监控、URI监控等
- 防御SQL注入:支持配置WallFilter
- 扩展性强:支持Filter-chain模式,可自定义拦截逻辑
- 中文文档齐全:国内开发者友好
重要提示:Spring Boot 3.x默认使用HikariCP,要切换Druid需要显式排除Hikari依赖
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础集成与配置
2.1 依赖配置
首先需要在pom.xml中添加以下依赖(注意排除HikariCP):
xml复制<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
2.2 基础配置参数
在application.yml中配置基本参数:
yaml复制spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
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
关键参数说明:
- initial-size:初始化连接数,建议与min-idle相同
- max-active:最大连接数,根据数据库配置和并发量调整
- max-wait:获取连接超时时间(毫秒)
- time-between-eviction-runs-millis:检测空闲连接的间隔时间
3. 高级功能配置
3.1 监控页面配置
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", "admin");
// 允许访问的IP,空表示所有
bean.addInitParameter("allow", "");
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;
}
}
启动应用后访问http://localhost:8080/druid即可看到监控页面。
3.2 SQL防火墙配置
Druid的WallFilter可以有效防御SQL注入:
yaml复制spring:
datasource:
druid:
filters: stat,wall
wall:
config:
drop-table-allow: false
alter-table-allow: false
3.3 多数据源配置
实际项目中经常需要配置多个数据源:
java复制@Configuration
public class MultiDataSourceConfig {
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties("spring.datasource.druid.primary")
public DataSource primaryDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties("spring.datasource.druid.secondary")
public DataSource secondaryDataSource() {
return DruidDataSourceBuilder.create().build();
}
}
对应application.yml配置:
yaml复制spring:
datasource:
druid:
primary:
url: jdbc:mysql://localhost:3306/db1
username: user1
password: pass1
secondary:
url: jdbc:mysql://localhost:3306/db2
username: user2
password: pass2
4. 性能调优与问题排查
4.1 连接泄露检测
Druid提供了连接泄露检测功能,在配置中添加:
yaml复制spring:
datasource:
druid:
remove-abandoned: true
remove-abandoned-timeout: 1800 # 30分钟
log-abandoned: true
当连接泄露时,会在日志中看到类似警告:
code复制WARN com.alibaba.druid.pool.DruidDataSource - abandon connection, owner thread: ...
4.2 常见问题排查
问题1:连接池耗尽
现象:报错"获取连接超时"
解决方案:
- 检查max-active是否设置过小
- 检查是否有连接泄露(未关闭Connection)
- 检查数据库最大连接数限制
问题2:监控页面无法访问
检查点:
- 是否配置了StatViewServlet
- 是否配置了正确的URL路径
- 检查Spring Security等安全框架是否拦截了/druid/*
4.3 性能优化建议
-
连接数设置:
- 初始值:CPU核心数 * 2 + 有效磁盘数
- 最大值:根据数据库服务器配置调整,通常不超过数据库max_connections的80%
-
超时时间:
- max-wait建议设置在1-3秒
- 避免设置过长导致线程堆积
-
监控建议:
- 生产环境建议关闭SQL详细日志(影响性能)
- 定期检查慢SQL列表并优化
5. 生产环境最佳实践
5.1 安全加固
- 修改监控页面路径:
避免使用默认的/druid路径
java复制bean.addUrlMappings("/custom-monitor/*");
- 配置访问IP白名单:
java复制bean.addInitParameter("allow", "192.168.1.100,127.0.0.1");
- 定期修改监控账号密码
5.2 与MyBatis整合优化
在mybatis-config.xml中配置:
xml复制<settings>
<setting name="defaultStatementTimeout" value="25"/>
</settings>
这样可以与Druid的配置协同工作,避免长时间运行的SQL占用连接。
5.3 动态配置调整
通过JMX可以动态调整参数:
java复制@Bean
public DruidStatManagerFacade druidStatManagerFacade() {
return DruidStatManagerFacade.getInstance();
}
然后通过JConsole等工具连接即可动态修改部分参数。
6. 监控指标解读
Druid监控页面提供了丰富的指标,关键指标包括:
- 活跃连接数:当前正在使用的连接数
- 等待线程数:等待获取连接的线程数
- 执行次数:SQL执行总次数
- 执行时间分布:各时间段的SQL执行情况
- 慢SQL:执行时间超过阈值的SQL
我通常特别关注以下几个指标:
- 活跃连接数长期接近max-active → 可能需要扩容
- 等待线程数持续大于0 → 连接获取存在瓶颈
- 慢SQL数量突然增加 → 可能有SQL性能问题
7. 与Spring Boot 3.x的兼容性问题
Spring Boot 3.x带来了一些变化需要注意:
- Jakarta EE 9+:Druid 1.2.x版本已适配
- 自动配置变化:部分配置项路径有调整
- 监控页面路径:需要确保不被Spring Security拦截
一个常见问题是监控页面静态资源加载失败,解决方案是在Security配置中添加:
java复制http.authorizeHttpRequests(auth -> auth
.requestMatchers("/druid/**").permitAll()
.requestMatchers("/css/**", "/js/**").permitAll()
);
8. 实际案例:电商系统配置实践
在某电商项目中,我们采用了如下配置:
yaml复制spring:
datasource:
druid:
# 基础配置
url: jdbc:mysql://cluster-xxx.rds.aliyuncs.com:3306/order_db
username: app_user
password: ${DB_PASSWORD}
initial-size: 10
max-active: 50
# 监控配置
stat-view-servlet:
enabled: true
url-pattern: /internal/db-monitor/*
allow: 10.0.0.0/8
# 过滤器配置
filters: stat,wall,slf4j
filter:
stat:
slow-sql-millis: 1000
log-slow-sql: true
wall:
config:
delete-allow: false
关键优化点:
- 使用VPC内网地址连接RDS
- 监控路径改为/internal下,限制内网访问
- 配置慢SQL阈值1秒并记录日志
- 禁止delete语句防止误操作
这套配置在双11大促期间稳定支撑了每秒3000+的订单处理量。
