什么是Druid连接池
Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。Druid 的优点主要有以下几个方面:
- 稳定性
- 为监控而生
- 诊断支持
- 防SQL注入
稳定性特性
稳定性是数据库连接池最关键的特性,由于设计并发和数据库系统的交互,稳定性需要由内置稳定保障机制和长时间大规模验证来保证
内置经过长期反馈验证过的ExceptionSorter
。在数据库服务器重启、网络抖动、连接被服务器关闭等异常情况下,连接发生了不可恢复异常,将连接从连接池中移除,保证连接池在异常发生情况下正常工作,是连接池稳定的关键特性。
错误提示:当连接不够用时,申请链接超时报错,Druid连接池能够报错会告诉你当前RunningSQL有哪些,当前连接池的水平信息。通过错误日志很方便知道系统瓶颈在哪里。
为监控而生
Druid连接池最初就是为监控系统采集jdbc运行信息而生的
- Druid连接池的监控信息主要是通过StatFilter 采集的,采集的信息非常全面,包括SQL执行、并发、慢查、执行时间区间分布等。
- Druid连接池内置了能和Spring/Servlet关联监控的实现,使得监控Web应用特别方便
- Druid连接池内置了一个监控页面,提供了非常完备的监控信息,可以快速诊断系统的瓶颈。
- 监控不影响性能,Druid增加StatFilter之后,能采集大量统计信息,同时对性能基本没有影响。StatFilter对CPU和内存的消耗都极小,对系统的影响可以忽略不计。监控不影响性能是Druid连接池的重要特性。
诊断支持
Druid连接池内置了LogFilter,将Connection/Statement/ResultSet相关操作的日志输出,可以用于诊断系统问题,也可以用于Hack一个不熟悉的系统。
LogFilter可以输出连接申请/释放,事务提交回滚,Statement的Create/Prepare/Execute/Close,ResultSet的Open/Next/Close,通过LogFilter可以详细诊断一个系统的Jdbc行为。
防SQL注入
SQL注入攻击是黑客对数据库进行攻击的常用手段,Druid连接池内置了WallFilter 提供防SQL注入功能,在不影响性能的同时防御SQL注入攻击。
- 基于语意的防SQL注入:Druid连接池内置了一个功能完备的SQL Parser,能够完整解析mysql、sql server、oracle、postgresql的语法,通过语意分析能够精确识别SQL注入攻击。
- 极低的漏报率和误报率:基于SQL语意分析,大量应用和反馈,使得Druid的防SQL注入拥有极低的漏报率和误报率。
- 防注入对性能影响极小:内置参数化后的Cache、高性能手写的Parser,使得打开防SQL注入对应用的性能基本不受影响。
druid-spring-boot-3-starter的使用
Druid Spring Boot Starter 用于帮助你在Spring Boot项目中轻松集成Druid数据库连接池和监控。
如何使用
在Spring Boot项目中添加>druid-spring-boot-3-starter
依赖
<!-- Druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
添加配置
spring:
datasource:
# driver-class-name 非必填可根据url推断
driver-class-name: com.mysql.cj.jdbc.Driver
# 只有下面三个是必填项(使用内嵌数据库的话这三个也可以不用填,会使用默认配置),其他配置不是必须的
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
druid: # druid连接池
initial-size: 2 # 初始化大小
max-active: 30 # 最大连接池数量
min-idle: 2 # 最小连接池数量
max-wait: 1234 # 连接时最大等待时间(单位:毫秒)
pool-prepared-statements: true # 是否缓存 PreparedStatement,默认为 false
max-pool-prepared-statement-per-connection-size: 5
# max-open-prepared-statements: #等价于上面的max-pool-prepared-statement-per-connection-size
validation-query: select 1 # 配置测试连接是否可用的查询 sql
validation-query-timeout: 1
test-on-borrow: true # 连接从连接池获取时是否测试连接的可用性
test-on-return: true # 连接返回连接池时是否测试连接的可用性。
test-while-idle: true # 连接空闲时是否执行检查。
time-between-eviction-runs-millis: 10000 # 配置多久进行一次检测,检测需要关闭的连接,单位是毫秒。
min-evictable-idle-time-millis: 30001 # 一个连接在连接池中最小生存的时间,单位是毫秒。
async-close-connection-enable: true
# 监控配置
# WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
# https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter
web-stat-filter:
enabled: true # 启动 StatFilter
# url-pattern: # 指定过滤url 例:/* 过滤所有url
# exclusions: # 排除一些不必要的url 例:"*.gif,*.jpg,*.png"
session-stat-enable: # 开启session统计功能
session-stat-max-count: # session的最大个数,默认100
principal-session-name: # Druid获取当前的session中存储的用户信息
principal-cookie-name: # Druid获取当前的cookie中存储的用户信息
profile-enable: # 打开能够监控单个url调用的sql列表
# StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
# https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
stat-view-servlet:
enabled: true #是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
url-pattern: /druid/* # 配置监控后台访问路径
# reset-enable:
login-username: admin # 配置监控后台登录的用户名、密码
login-password: admin
# allow:
# deny:
# Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置
# aop-patterns: # Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
# 配置StatFilter
filter:
stat:
enabled: true
# db-type:
log-slow-sql: true # 开启慢 sql 记录
slow-sql-millis: 2000 # 若执行耗时大于 2s,则视为慢 sql
# 配置WallFilter
wall:
enabled: true
# db-type:
config:
delete-allow: false
drop-table-allow: false
# 其他 Filter 配置可根据官方文档自动选择
访问监控后台
出现以下提示就表示配置成功,可以通过配置好的监控后台访问路径进行访问
使用druid加密密码
package com.leemuzi.druid;
import com.alibaba.druid.filter.config.ConfigTools;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Slf4j
class DruidApplicationTests {
@Test
@SneakyThrows
void testEncodePassword() {
// 你的密码
String password = "123456";
String[] arr = ConfigTools.genKeyPair(512);
// 私钥
log.info("privateKey: {}", arr[0]);
// 公钥
log.info("publicKey: {}", arr[1]);
// 通过私钥加密密码
String encodePassword = ConfigTools.encrypt(arr[0], password);
log.info("password: {}", encodePassword);
}
}
spring:
datasource:
// 省略...
username: root
password: I6LsOdIbnlLxBLV5Dw0+zr9OE0u/oMKh1w2i2yrPFXHMjDwp1qpXZB4up3ZvJt/QCPrHcHcIJ37hEOuEo7OadA== # 数据库密码
druid: # Druid 连接池
// 省略...
connectionProperties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ2rEicHO9sXBpa9Efxw74o1rJiwiODKY3znwH2K/f1yf4M9ZbyAuqMKm2DjffHa7Ol4S6ZuLtoNnzomgn/tPGcCAwEAAQ==
// 省略...
filter:
config:
enabled: true
// 省略...
- assword: A2qT03X7KlL4v/F2foD6kV/Ch9gpNBWOh1qoCywanjv1AsI7f9x3iAyR9NkUKeV+FMo+halCTzy5Llbk2VOrVQ==:这里的密码改为加密后的密码。
- config.decrypt=true 表示开启密码解密功能
- config.decrypt.key 是用于解密的密钥,即上面单元测试生成公钥。
- 在 Druid 连接池中,如果我们的密码已经经过了加密处理,就需要在连接属性中配置解密相关的参数,以便 Druid 能够正确解密密码,然后连接到数据库。
- filter.config.enabled: true:这里配置了 Druid 连接池的 filter,其中 config 是一个配置项,enabled: true 表示开启该配置项。这个配置项通常用于配置 Druid 连接池的一些额外功能,比如密码解密等。