SpringBoot + Druid 统计、监控 SQL 运行情况

1. 基本概念

Druid 是 Java 语言中最好的数据库连接池。
虽然 HikariCP 的速度稍快,但是,Druid 能够提供强大的监控和扩展功能。
而 Druid 已经在阿里巴巴部署了超过600个引用,经过好几年生产环境大规模部署的严苛考验!

  • stat: Druid 内置提供一个 StatFilter,用于统计监控信息。
  • wall: Druid 防御 SQL 注入攻击的 WallFilter 就是通过 Druid 的 SQL Parser 分析。Druid 提供的 SQL Parser 可以在 JDBC 层拦截 SQL 做相应处理,比如说分库分表、审计等。
  • log4j2: 这个就是日志记录的功能,可以把 sql 语句打印到 Log4j2 供排查问题。

2. 添加依赖

项目 pom.xml 文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.9</version>
        <relativePath />
    </parent>

    <groupId>com.ninaco.xms</groupId>
    <artifactId>xms</artifactId>
    <version>1.0.0</version>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.zaxxer</groupId>
                    <artifactId>HikariCP</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
            <exclusions>
                <exclusion>
                    <groupId>com.zaxxer</groupId>
                    <artifactId>HikariCP</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3. 配置相关属性

application.yml

# 配置数据源(Druid)
spring:
  datasource:
    # JDBC 基本配置
    username: xxx
    password: xxx
    driver-class-name: com.mysql.cj.jdbc.Driver # mysql8 驱动
    url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=Asia/Shanghai
    type: com.alibaba.druid.pool.DruidDataSource # 指定数据源
    # 连接池配置
    druid:
      # 配置初始化大小、最小、最大
      initial-size: 5
      min-idle: 10
      max-active: 20
      # 配置获取连接等待超时的时间(单位:毫秒)
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空箱连接,单位是毫秒
      time-between-eviction-runs-millis: 200
      # 配置一个连接在池中最小生存的世界,单位是毫秒
      min-evictable-idle-time-millis: 600000
      max-evictable-idle-time-millis: 900000
      # 用来测试连接是否可用的SQL语句,默认值每种数据库都不相同,这是 mysql
      validation-query: select 1
      # 应用向连接池申请连接,并且 testOnBorrow 为false时,连接池将会判断连接是否处于空闲状态,如果是,则验证这条连接是否可用
      test-while-idle: true
      # 如果为 true,默认是false,应用向连接池申请连接时,连接池会判断这条连接是否是可用的
      test-on-borrow: false
      # 如果为 true(默认 false),当应用使用完连接,连接池回收连接的时候会判断改连接是否还可用
      test-on-return: false
      # 是否缓存 preparedStatement,也就是 PSCache。PSCache对支持游标的数据库性能提升巨大,比如 oracle
      pool-prepared-statements: true
      # 要启用 PSCache,必须配置大于0,当大于0时,poolPreparedStatements 自动触发修改为 true,
      # 在 Druid 中,不会存在 Oracle下 PSCache 占用内存过多的问题,可以吧这个数值配置大一些,比如说 100
      max-open-prepared-statements: 20
      # 连接池中的 minIdle 数量以内的连接,空闲时间超过 minEVictableIdleTimeMillis,则会执行 keepAlive 操作
      keep-alive: true
      # Spring 监控,利用 aop 对指定接口的执行时间,jdbc数进行记录
      aop-patterns: "com.ninaco.xms.dao.*"
      ## 启用内置过滤器(第一个 stat 必须,否则监控不到 SQL)
      filters: stat,wall,log4j2
      # 自己配置监控统计拦截的 filter
      filter:
        # 开启 druiddatasource 的状态监控
        stat:
          enabled: true
          db-type: mysql
          # 开启慢 sql 监控,超过 2s 就认为是 慢 sql,记录到日志中
          log-slow-sql: true
          slow-sql-millis: 2000
        # 日志监控,使用 slf4j2 进行日志输出
        slf4j:
          enabled: true
          statement-log-error-enabled: true
          statement-create-after-log-enabled: false
          statement-close-after-log-enabled: false
          result-set-open-after-log-enabled: false
          result-set-close-after-log-enabled: false
      ## 配置 WebStatFilter,用于采集 web 关联监控的数据
      web-stat-filter:
        # 启动 StatFilter
        enabled: true
        # 过滤所有 url
        url-pattern: /*
        # 排除一些不必要的url
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
        # 开启 session 统计功能
        session-stat-enable: true
        # session 的最大个数,默认100
        session-stat-max-count: 1000
      ## 配置 StatViewServlet(监控页面),用于展示 Druid 的统计信息
      stat-view-servlet:
        # 启用 StatViewServlet
        enabled: true
        # 访问内置监控页面的路径,内置监控页面的首页是 /druid/index.html
        url-pattern: /druid/*
        # 不允许清空统计数据,重新计算
        reset-enable: false
        # 配置监控页面访问用户和密码
        login-username: root
        login-password: 123
        # 允许访问的地址,如果 allow 没有配置或者为空,则允许所有访问
        allow: 127.0.0.1
        # 拒绝访问的地址,deny优先于 allow,如果在 deny 列表中,就算在 allow 列表中,也会被拒绝
        deny:

上述配置文件的参数可以在 com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatPropertiesorg.springframework.boot.autoconfigure.jdbc.DataSourceProperties中找到;

4. 监控界面

  1. 启动项目后,访问 /druid/login.html 来到登录页面,输入用户名密码登录
    image
  2. 数据源页面是当前 DataSource 配置的基本信息,上述配置的 Filter 可以在里面找到,如果没有配置 Filter(一些信息会无法统计,例如“SQL 监控”,会无法获取 JDBC 相关的 SQL 执行信息)
    image
  3. SQL 监控页面,统计了所有 SQL 语句的执行情况
  4. URL 监控页面,统计了所有 Controller 接口的访问以及执行情况
  5. Spring 监控页面,利用 aop 对指定接口的执行时间,jdbc 数进行记录
  6. SQL 防火墙页面,druid 提供了黑白名单的访问,可以清楚的看到 sql 防护情况
  7. Session 监控页面,可以看到当前的 session 状况,创建时间、最后的活跃时间、请求次数、请求时间等详细参数。
  8. JSONAPI 页面,通过 api 的形式访问 Druid 的监控接口,api放回 json 形式数据

5. spring 监控

访问之后 spring 讲课默认是没有数据的;这需要导入 SpringBoot 的 AOP 的 Starter

<!--SpringBoot 的aop 模块-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

之后在 application.yml 配置 AOP 切入点

spring:
  datasource:
    druid:
      # Spring 监控,利用 aop 对指定接口的执行时间,jdbc数进行记录
      aop-patterns: "com.ninaco.xms.dao.*"

Spring 监控 AOP 切入点,如 com.ninaco.xms.dao.*, 配置多个英文逗号分隔

6. 获取 Druid 的监控数据

Druid 的监控数据可以在 开启 StatFilter 后,通过 DruidStatManagerFacade 进行获取;
DruidStatManagerFacade#getDataSourceStatDataList 该方法可以获取所有数据源的监控数据,除此之外 DruidStatManagerFacade 还提供了一些其他方法,可以按需选择使用。

@RestController
@RequestMapping("/druid")
public class DruidStatController {

    @GetMapping("/stat")
    public Object druidStat() {
        // 获取数据源的监控数据
        return DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
    }

}
posted @   疑问号?  阅读(1078)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示