在上篇文章中分析了数据连接池(Durid)在应用中可以做到资源重用,提升系统响应速度,避免数据库连接遗漏。它除了是一个高性能数据库连接池之外,更是一个自带监控的数据库连接池 JDDC与Druid
1Druid是什么
Apache Druid是一个实时分析型数据库,旨在对大型数据集进行快速的查询分析("OLAP"查询)。Druid最常被当做数据库来用以支持实时摄取、高性能查询和高稳定运行的应用场景,同时,Druid也通常被用来助力分析型应用的图形化界面,或者当做需要快速聚合的高并发后端API,Druid最适合应用于面向事件类型的数据。
Druid通常应用于以下场景:
- 点击流分析(Web端和移动端)
- 网络监测分析(网络性能监控)
- 服务指标存储
- 供应链分析(制造类指标)
- 应用性能指标分析
- 数字广告分析
- 商务智能 / OLAP
2 SpringBoot 整合Druid
为了演示Druid的监控功能,这里采用JDBCTemplate来作为sql操作模块
2.1 引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
2.2 Druid配置
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/face?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: Liuyifei@@
# 初始化连接数
initial-size: 10
# 最大连接
max-active: 20
# 连接池中最小连接
min-idle: 1
# 获得连接最长等待的时间 毫秒
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接 单位毫秒 60000ms=60s=1min
timeBetweenEvictionRunsMillis: 60000
# 连接最小生存的时间 单位毫秒 300000ms=300s=5min
minEvictableIdleTimeMillis: 300000
# 应用向连接池申请连接,并且testOnBorrow为false时,连接池将会判断连接是否处于空闲状态,如果是,则验证这条连接是否可用
test-while-idle: true
# 如果为true(默认false),应用向连接池申请连接时,连接池会判断这条连接是否是可用的
test-on-borrow: false
# 如果为true(默认false),当应用使用完连接,连接池回收连接的时候会判断该连接是否还可用
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 20
validation-query-timeout: 500
validation-query: select 1
# 启用内置过滤器 stat
filters: stat
filter:
stat:
db-type: mysql
# 开启慢sql监控,超过2s 就认为是慢sql,记录到日志中
log-slow-sql: true
slow-sql-millis: 2000
enabled: true
# Druid监测
stat-view-servlet:
enabled: true # 启用StatViewServlet
url-pattern: /druid/* # 访问内置监控页面的路径,内置监控页面的首页是/druid/index.html
reset-enable: false # 不允许清空统计数据,重新计算
allow: 127.0.0.1 # 允许访问的地址,如果allow没有配置或者为空,则允许所有访问
deny: 10.157.147.143 # 拒绝访问的地址,deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝
login-password: admin # 配置监控页面访问密码
login-username: admin # 配置监控页面访问账号
web-stat-filter:
enabled: true
url-pattern: /* # 对所有url进行监控
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" # 排除一些不必要的url
session-stat-enable: true
session-stat-max-count: 200
2.3 模拟DAO层
@Service
public class UserService {
@Autowired
private JdbcTemplate template;
/**
* 查询所有讲师列表
* @return
*/
public List<User> getUserList(){
List<User> users = template.query("select * from uuser", (resultSet, i) -> {
User user = new User();
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
user.setRoot(resultSet.getString("root"));
return user;
});
return users;
}
/**
* 创建用户信息
*/
public int createUser(String name,String password,String root){
return template.update("insert into uuser(username,password,root) values(?, ?,?)", name,password,root);
}
/**
* 删除用户id
* @param id
* @return
*/
public int delUserById(int id){
return template.update("delete from uuser where id = ?", id);
}
/**
* 查询总数
* @return
*/
public int getUserCount() {
return template.queryForObject("select count(1) from uuser", Integer.class);
}
}
2.4 模拟Controller
@RestController()
public class UserDemoController {
@Autowired
private UserService service;
@GetMapping("/getUserList")
/**
* 查询所有讲师列表
* @return
*/
public List<User> getUserList(){
return service.getUserList();
}
@PostMapping("/createUser")
/**
* 创建用户信息
*/
public int createUser(@RequestBody User user){
return service.createUser(user.getUsername(), user.getPassword(),user.getRoot());
}
@DeleteMapping("/id")
/**
* 删除用户id
* @param id
* @return
*/
public int delUserById(@PathVariable int id){
return service.delUserById(id);
}
@GetMapping("/getUserCount")
/**
* 查询总数
* @return
*/
public int getUserCount() {
return service.getUserCount();
}
}
3 Druid监控
完成上面所有配置之后,启动应用,访问Druid的监控页面http://localhost:8080/druid/,可以看到如下登录页面:
输入application.yml配置中spring.datasource.druid.stat-view-servlet.login-username
(admin)和spring.datasource.druid.stat-view-servlet.login-password
(admin)配置的登录账户与密码,就能看到如下监控页面:
数据源页面:这里可以看到之前我们配置的数据库连接池信息以及当前使用情况的各种指标。
SQL监控页面,统计了所有SQL语句的执行情况
图中监控项上,执行时间、读取行数、更新行数都通过区间分布的方式表示,将耗时分布成8个区间:
- 0 - 1 耗时0到1毫秒的次数
- 1 - 10 耗时1到10毫秒的次数
- 10 - 100 耗时10到100毫秒的次数
- 100 - 1,000 耗时100到1000毫秒的次数
- 1,000 - 10,000 耗时1到10秒的次数
- 10,000 - 100,000 耗时10到100秒的次数
- 100,000 - 1,000,000 耗时100到1000秒的次数
- 1,000,000 - 耗时1000秒以上的次数
URI监控页面:统计了所有Controller接口的访问以及执行情况
Session监控页面:可以看到当前的session状况,创建时间、最后活跃时间、请求次数、请求时间等详细参数。