1. 为什么需要Druid连接池
在Spring Boot应用中直接使用原生JDBC连接数据库会面临几个典型问题。每次请求都创建新连接,完成操作后立即关闭,这种模式在高并发场景下会导致严重的性能瓶颈。我曾在压力测试中观察到,每秒200个请求时,单纯创建连接就消耗了70%的响应时间。
连接池的核心价值在于复用已建立的数据库连接。Druid作为阿里开源的连接池实现,相比HikariCP等方案提供了更全面的监控功能。通过内置的StatFilter,我们能实时获取SQL执行情况、连接等待时间等关键指标。去年处理过一个生产环境故障,正是通过Druid的监控界面快速定位到某个慢SQL占用了80%的连接资源。
Druid 1.2.8版本开始全面支持JDK 17和Spring Boot 3.x。其独特的防SQL注入功能通过WallFilter实现,这在金融类项目中尤为重要。我曾参与的一个支付系统项目,通过配置wall.config.deleteAllow=false有效阻止了全表删除操作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础环境搭建
2.1 依赖配置要点
在pom.xml中需要同时引入druid-spring-boot-starter和spring-boot-starter-data-jpa(或jdbc)。特别注意版本兼容性:
xml复制<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
常见踩坑点:部分教程仍在使用旧版druid-spring-boot-starter(不带3后缀),这会导致Spring Boot 3自动配置失败。我最近在团队内部技术分享时就遇到有同事因此浪费了两小时排查时间。
2.2 基础配置参数
application.yml中最关键的几项配置:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/demo?useSSL=false
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
参数设置经验:
- initial-size不宜过大,通常5-10即可,我曾在测试环境设置initial-size=50导致数据库连接数瞬间飙高
- max-active需要根据服务器核心数调整,建议公式:CPU核心数 * 2 + 有效磁盘数
- max-wait单位是毫秒,超过该值会抛出异常,生产环境建议设置在1-3秒
3. 监控中心配置实战
3.1 控制台基础配置
启用监控控制台需要添加以下配置:
yaml复制spring:
datasource:
druid:
stat-view-servlet:
enabled: true
login-username: admin
login-password: druid123
allow: 127.0.0.1
deny: 192.168.1.100
安全建议:
- 必须修改默认账号密码(曾发生过多起因使用admin/admin导致的安全事件)
- 通过allow/deny限制访问IP,特别是生产环境
- 建议配合Spring Security做二次鉴权
3.2 SQL监控配置
要捕获SQL执行统计,需添加Filter配置:
java复制@Configuration
public class DruidConfig {
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean =
new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
// ...参数配置
return bean;
}
@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter() {
FilterRegistrationBean<WebStatFilter> bean =
new FilterRegistrationBean<>(new WebStatFilter());
bean.addUrlPatterns("/*");
bean.addInitParameter("exclusions", "*.js,*.gif,/druid/*");
return bean;
}
}
常见问题排查:
- 监控页面显示"No datasource":检查是否配置了spring.datasource.druid.filters=stat
- SQL监控无数据:确认没有使用@Transactional(readOnly=true),这类操作默认不被统计
4. 高级功能配置
4.1 防SQL注入配置
WallFilter配置示例:
yaml复制spring:
datasource:
druid:
filter:
wall:
enabled: true
config:
delete-allow: false
drop-table-allow: false
multi-statement-allow: true
实际案例:某电商平台曾因未启用WallFilter导致通过订单查询接口注入drop语句。建议测试环境开启所有防护,生产环境根据实际情况调整multi-statement-allow等参数。
4.2 连接泄露检测
对于长时间运行的查询,需要配置:
yaml复制spring:
datasource:
druid:
remove-abandoned: true
remove-abandoned-timeout: 300
log-abandoned: true
参数说明:
- remove-abandoned-timeout单位是秒,建议设置为业务最长查询时间的2倍
- 开启log-abandoned后会在日志中记录堆栈信息,有助于定位问题代码
我在金融项目中遇到过连接泄露问题,通过该配置发现是某个批量处理未正确关闭连接。日志中会显示类似"abandoned connection, owner thread..."的警告。
5. 性能优化实践
5.1 连接池参数调优
生产环境推荐配置:
yaml复制spring:
datasource:
druid:
# 连接池大小
initial-size: 10
min-idle: 10
max-active: 50
# 性能相关
max-wait: 1000
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
调优经验:
- time-between-eviction-runs-millis不宜过小,否则影响性能
- 使用MySQL时validation-query建议用SELECT 1而非原生ping命令
- test-on-borrow在生产环境应设为false,否则每个请求都验证会影响性能
5.2 多数据源配置
大型项目常需要多数据源,配置示例:
java复制@Configuration
public class MultiDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.master")
public DataSource masterDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.slave")
public DataSource slaveDataSource() {
return DruidDataSourceBuilder.create().build();
}
}
注意事项:
- 每个数据源需要独立的监控页面路径
- 事务管理需要使用JtaTransactionManager或ChainedTransactionManager
- 建议为不同数据源配置不同的连接名前缀便于监控
6. 生产环境问题排查
6.1 连接池耗尽分析
典型错误信息:"com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 20"
排查步骤:
- 查看druid监控的"连接堆栈"页面,找出占用连接的线程
- 检查是否有未关闭的连接(重点关注StreamingResultSet场景)
- 分析SQL执行时间是否过长
临时解决方案:
java复制// 应急情况下可临时增加
spring.datasource.druid.max-active=50
但根本解决需要找到泄漏点。我曾遇到一个案例:使用MyBatis的ResultHandler处理大数据量时未正确关闭会话。
6.2 监控页面访问控制
当出现"Sorry, you are not permitted to view this page"时:
- 检查登录账号密码是否正确
- 确认IP不在deny列表
- 查看是否配置了resetEnable=false
安全建议:将监控页面路径从默认的/druid改为自定义路径,如/internal-monitor,可减少自动化攻击风险。
