Druid 是一个用 Java 编写的面向列的开源分布式数据存储。 Druid 被设计来快速摄取大量事实数据,并在数据之上提供低延迟查询。Druid 这个名字来自于许多角色扮演游戏中的变形德鲁伊类角色,以反映系统架构可以迁移到解决不同类型的数据问题的特性。 Druid 通常用于商业智能 / OLAP 应用程序,以分析大量的实时和历史数据。

(Druid读音 英:[ˈdruːɪd] 美:[ˈdruːɪd])

Druid可以做什么?

1) 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。

2) 替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。

3) 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。

4) SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。

扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter-Chain机制,很方便编写JDBC层的扩展插件。

SpringBoot整合Druid

我的版本:

SpringBoot:2.3.1

druid:1.1.23

配置maven

Druid 0.1.18 之后版本都发布到maven中央仓库中,所以你只需要在项目的pom.xml中加上dependency就可以了。例如:

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid-version}</version>
</dependency>

配置application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
spring:
datasource:
# 数据源基本配置 JDBC配置
username: root #数据库用户名
password: 123456 #数据库密码
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/databaseName?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
type: com.alibaba.druid.pool.DruidDataSource #数据源类型
# 数据源其他配置 连接池配置
initialSize: 5 #配置初始化大小、最小、最大
minIdle: 5
maxActive: 20
maxWait: 60000 #配置获取连接等待超时的时间
timeBetweenEvictionRunsMillis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 #配置一个连接在池中最小生存的时间,单位是毫秒
validationQuery: SELECT 1 FROM DUAL #验证连接有效与否的SQL,不同的数据配置不同
testWhileIdle: true #如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true #打开PSCache
maxPoolPreparedStatementPerConnectionSize: 20 #最大PSCache连接
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
#开启Druid的监控统计功能,StatFilter可以和其他的Filter配置使用
filters: stat,wall,slf4j #过滤器设置,默认日志框架为log4j
useGlobalDataSourceStat: true #合并多个DruidDataSource的监控数据
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录

编写Druid配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Configuration
public class DruidConfig {

//告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid(){
return new DruidDataSource();
}

//配置Druid的监控
//1、配置一个管理后台的Servlet
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
//访问http://localhost:8080/druid/
initParams.put("loginUsername", "admin"); //登录账号
initParams.put("loginPassword", "123456");//登录密码
initParams.put("allow", ""); //默认就是允许所有访问;
// initParams.put("deny", "192.168.15.21"); //拒绝访问
bean.setInitParameters(initParams);

return bean;
}

//2、配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());

Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,/druid/*");
bean.setInitParameters(initParams);

bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}

Druid Spring Boot Starter

SpringBoot2.0整合Druid数据源可以加入druid-spring-boot-starter依赖。

Druid Spring Boot Starter 用于帮助你在Spring Boot项目中轻松集成Druid数据库连接池和监控。

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid-version}</version>
</dependency>

Druid Spring Boot Starter 配置属性的名称完全遵照 Druid,你可以通过 Spring Boot 配置文件来配置Druid数据库连接池和监控,如果没有配置则使用默认值。,可以省去原本写Druid的一些配置文件或者@Configuration来配置,直接将配置写在application.yml里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
spring:
datasource:
# 使用阿里的Druid连接池
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
# 填写你数据库的url、登录名、密码和数据库名
url: jdbc:mysql://localhost:3306/databaseName?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
druid:
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
# 配置DruidStatFilter
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
# 配置DruidStatViewServlet
stat-view-servlet:
url-pattern: "/druid/*"
# IP白名单(没有配置或者为空,则允许所有访问)
allow: 127.0.0.1,192.168.163.1
# IP黑名单 (存在共同时,deny优先于allow)
deny: 192.168.1.73
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# 登录名
login-username: admin
# 登录密码
login-password: 123456

使用数据库连接池的意义

建立数据库连接耗时耗费资源,一个数据库服务器能够同时建立的连接数也是有限的,在大型的Web应用中,可能同时会有成百上千的访问数据库的请求,如果Web应用程序为每一个客户请求分配一个数据库连接,将导致性能的急剧下降。
数据库连接池的意义在于,能够重复利用数据库连接(有点类似线程池的部分意义),提高对请求的响应时间和服务器的性能。连接池中提前预先建立了多个数据库连接对象,然后将连接对象保存到连接池中,当客户请求到来时,直接从池中取出一个连接对象为客户服务,当请求完成之后,客户程序调用close()方法,将连接对象放回池中。

在普通的数据库访问程序中,客户程序得到的连接对象是物理连接,调用连接对象的close()方法将关闭连接,而采用连接池技术,客户程序得到的连接对象是连接池中物理连接的一个句柄,调用连接对象的close()方法,物理连接并没有关闭,数据源的实现只是删除了客户程序中的连接对象和池中的连接对象之间的联系。