Druid(全称 Alibaba Druid )是阿里巴巴开源的高性能数据库连接池,同时也是数据库监控与防御工具。它不仅实现了传统连接池的核心功能(如连接复用、生命周期管理),还提供了丰富的扩展能力(如 SQL 监控、慢查询分析、SQL 防火墙、连接泄漏检测等),是 Java 生态中最主流的数据库连接池之一(尤其在 Spring Boot 项目中广泛使用)。
一、Druid 的核心作用
Druid 的核心价值在于高效管理数据库连接,并通过扩展功能解决数据库使用中的常见问题。具体作用可分为以下几类:
1. 连接池基础功能
- 连接复用:预先创建并缓存一定数量的数据库连接,避免频繁创建/销毁连接的开销(TCP 三次握手、数据库认证等耗时操作)。
- 连接生命周期管理:自动回收空闲连接、验证连接有效性(防止"僵尸连接")、控制最大/最小连接数,避免资源浪费或耗尽。
- 线程安全:通过同步机制保证多线程环境下连接的正确分配与回收。
2. 性能优化
- 连接池状态监控:实时统计连接池的使用情况(活跃连接数、空闲连接数、等待队列长度等),帮助定位连接泄漏或配置不合理问题。
- 慢查询统计:记录执行时间超过阈值的 SQL,辅助优化数据库性能。
- 预编译语句缓存:缓存常用 SQL 的预编译语句(PreparedStatement),减少重复解析 SQL 的开销。
3. 安全与防御
- SQL 防火墙 :通过规则过滤危险 SQL(如
DROP TABLE
、TRUNCATE
),防止 SQL 注入攻击(需自定义规则)。 - 连接泄漏检测:跟踪未关闭的连接,记录泄漏的调用栈,帮助开发者快速定位未释放连接的代码。
- 密码加密:支持对数据库密码进行加密存储(如 AES),避免明文密码泄露。
二、Druid 的典型使用场景
Druid 适用于需要高性能数据库访问 、详细监控 或安全防护的场景,例如:
- 生产环境的数据库连接管理(替代 HikariCP、DBCP 等传统连接池);
- 微服务架构中对数据库操作的统一监控与治理;
- 需要防御 SQL 注入攻击的关键业务系统;
- 慢查询定位与 SQL 性能优化场景。
三、Druid 的用法详解(以 Spring Boot 为例)
在 Spring Boot 项目中集成 Druid 非常简单,主要分为添加依赖 、配置参数 、使用与扩展三个步骤。
1. 添加 Maven 依赖
在 pom.xml
中引入 Druid 的 Starter(Spring Boot 2.x 推荐使用 druid-spring-boot-starter
):
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version> <!-- 最新版本可查 Maven 仓库 -->
</dependency>
<!-- 若需监控页面,需额外引入 servlet 依赖(Spring Boot 已内置) -->
2. 配置 Druid 参数
在 application.yml
或 application.properties
中配置 Druid 连接池参数。以下是核心配置项说明:
配置项 | 类型 | 说明 | 推荐值/默认值 |
---|---|---|---|
url |
String | 数据库连接 URL(必填) | - |
username |
String | 数据库用户名(必填) | - |
password |
String | 数据库密码(必填,支持加密) | - |
driver-class-name |
String | 数据库驱动类名(如 com.mysql.cj.jdbc.Driver ) |
自动推断(可选) |
initial-size |
int | 初始化时创建的连接数 | 5(默认) |
max-active |
int | 最大活跃连接数(连接池能提供的最大连接数) | 20(默认) |
min-idle |
int | 最小空闲连接数(保持的空闲连接数) | 5(默认,建议等于 initial-size) |
max-wait |
long | 获取连接的最大等待时间(毫秒,超时抛异常) | 30000(默认) |
validation-query |
String | 验证连接有效性的 SQL(如 MySQL 的 SELECT 1 ) |
无(建议配置) |
test-while-idle |
boolean | 空闲时是否验证连接有效性(配合 time-between-eviction-runs-millis ) |
true(推荐) |
time-between-eviction-runs-millis |
long | 空闲连接检测周期(毫秒,用于回收过期连接) | 60000(默认,1分钟) |
filters |
String | 启用 Druid 的扩展功能(如监控、防火墙) | stat,wall,log4j2 (常用组合) |
stat-view-servlet.enabled |
boolean | 是否启用监控页面(Web 界面) | false(默认,需手动开启) |
stat-view-servlet.url-pattern |
String | 监控页面的访问路径 | /druid/* (默认) |
stat-view-servlet.login-username |
String | 监控页面的登录用户名 | -(需配置) |
stat-view-servlet.login-password |
String | 监控页面的登录密码 | -(需配置) |
示例配置(application.yml):
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456 # 实际生产环境建议加密
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource # 显式指定 Druid 数据源(可选,Starter 自动配置)
druid:
initial-size: 5
max-active: 20
min-idle: 5
max-wait: 30000
validation-query: SELECT 1
test-while-idle: true
time-between-eviction-runs-millis: 60000
# 启用监控、SQL 防火墙、慢查询统计
filters: stat,wall,slf4j
# 监控页面配置
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: admin123
# SQL 防火墙(阻止 DROP、TRUNCATE 等危险操作)
web-stat-filter:
enabled: true
url-pattern: /*
3. 使用 Druid 连接池
在 Spring Boot 中,Druid 会自动配置为 DataSource
Bean,无需手动创建。业务代码通过 @Autowired
注入 JdbcTemplate
或 MyBatis
的 SqlSessionFactory
即可使用,与普通连接池用法一致:
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate; // 由 Druid 数据源驱动
public User getUserById(Long id) {
return jdbcTemplate.queryForObject(
"SELECT * FROM user WHERE id = ?",
new Object[]{id},
(rs, rowNum) -> new User(
rs.getLong("id"),
rs.getString("name"),
rs.getString("email")
)
);
}
}
4. 高级功能使用
Druid 的扩展功能(如监控、防火墙)需要额外配置,以下是常见场景:
(1)查看监控页面
配置 stat-view-servlet.enabled=true
后,启动项目访问 http://localhost:8080/druid
,输入配置的用户名和密码(如 admin/admin123
),可查看:
- 数据源基本信息(连接数、SQL 执行量等);
- SQL 监控(执行时间、频率、慢查询列表);
- URI 监控(各接口的数据库操作统计);
- Session 监控(当前活跃连接数)。
(2)SQL 防火墙(防注入)
通过 wall
过滤器配置 SQL 规则,阻止危险操作。例如,在 application.yml
中添加:
spring:
datasource:
druid:
filters: wall
wall:
config:
# 禁止 DROP TABLE
drop-table-allow: false
# 禁止 TRUNCATE
truncate-allow: false
# 允许的 SQL 函数(防止恶意函数调用)
function-allow: "substring,concat"
(3)慢查询统计
通过 stat
过滤器记录执行时间超过阈值的 SQL。在配置中添加:
spring:
datasource:
druid:
filters: stat
stat:
log-slow-sql: true # 记录慢 SQL
slow-sql-millis: 2000 # 超过 2000ms 视为慢 SQL
merge-sql: true # 合并相同 SQL 的统计
慢 SQL 日志会输出到控制台或日志文件(取决于日志配置),示例:
2024-03-10 12:00:00 [Druid-StatLogger] INFO slow sql 2500ms : SELECT * FROM order WHERE create_time < '2020-01-01'
(4)连接泄漏检测
Druid 可以跟踪未关闭的连接,并记录泄漏的调用栈。配置如下:
spring:
datasource:
druid:
remove-abandoned: true # 启用连接泄漏检测
remove-abandoned-timeout: 300 # 连接未关闭超过 300 秒则强制回收
log-abandoned: true # 记录泄漏连接的创建位置(调用栈)
当发生连接泄漏时,日志会输出类似以下信息:
DEBUG com.alibaba.druid.pool.DruidDataSource - abandon connection, ownerThread: http-nio-8080-exec-1, stackTrace:
java.lang.Exception: trace DruidConnectionHolder
at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1183)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1151)
at com.example.service.UserService.getUserById(UserService.java:25) # 泄漏连接的代码位置
四、Druid 与其他连接池的对比
特性 | Druid | HikariCP | DBCP2 |
---|---|---|---|
连接管理 | 支持连接泄漏检测、慢查询统计 | 轻量级,侧重性能 | 传统连接池,功能较基础 |
监控能力 | 内置丰富监控(SQL、连接、URI) | 仅基础指标(活跃连接数等) | 无内置监控,需扩展 |
安全功能 | SQL 防火墙、密码加密 | 无 | 无 |
适用场景 | 需要监控/安全的复杂系统 | 高性能要求的简单场景 | 传统项目兼容 |
配置复杂度 | 较高(功能多) | 简单(默认配置即可) | 中等 |
五、注意事项
- 密码加密 :生产环境中避免明文存储密码,可通过
druid.password.callback
配置密码加密器(如 AES)。 - 连接泄漏 :务必在
finally
块或使用try-with-resources
关闭连接(如Connection.close()
),否则可能触发连接泄漏报警。 - 监控性能 :启用过多监控功能(如
stat
、wall
)会增加轻微开销,生产环境建议按需启用。 - 版本兼容性 :Druid 与 Spring Boot、数据库驱动版本需匹配(如 MySQL 8.0 需使用
com.mysql.cj.jdbc.Driver
)。
总结
Druid 是一个功能全面的数据库连接池,不仅解决了连接管理的核心问题,还通过监控、安全等扩展功能成为企业级应用的"瑞士军刀"。在 Spring Boot 项目中,只需简单配置即可集成,适用于需要高性能、高可靠性或强监控需求的数据库访问场景。