关于java:Spring-Boot-如何统计监控-SQL-运行情况写得太好了

5次阅读

共计 9036 个字符,预计需要花费 23 分钟才能阅读完成。

起源:juejin.cn/post/7062506923194581029

1 基本概念

Druid 是 Java 语言中最好的数据库连接池。

尽管 HikariCP 的速度稍快,然而,Druid 可能提供弱小的监控和扩大性能,也是阿里巴巴的开源我的项目。

Druid 是阿里巴巴开发的号称为监控而生的数据库连接池,在性能、性能、扩展性方面,都超过其余数据库连接池,包含 DBCP、C3P0、BoneCP、Proxool、JBoss DataSource 等等等,秒杀所有。

Druid 能够很好的监控 DB 池连贯和 SQL 的执行状况,天生就是针对监控而生的 DB 连接池。

Spring Boot 默认数据源 HikariDataSource 与 JdbcTemplate 中曾经介绍 Spring Boot 2.x 默认应用 Hikari 数据源,能够说 Hikari 与 Driud 都是以后 Java Web 上最优良的数据源。

而 Druid 曾经在阿里巴巴部署了超过 600 个利用,通过好几年生产环境大规模部署的严苛考验!

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

2 增加依赖

pom.xml

<!-- 阿里巴巴的 druid 数据源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.23</version>
</dependency>
<!-- mysql8 驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- 应用 log4j2 记录日志 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

<!--
mybatis,引入了 SpringBoot 的 JDBC 模块,所以,默认是应用 hikari 作为数据源
-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
    <exclusions>
        <!-- 排除默认的 HikariCP 数据源 -->
        <exclusion>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3 配置相干属性

配置 Druid 数据源(连接池): 如同以前 c3p0、dbcp 数据源能够设置数据源连贯初始化大小、最大连接数、等待时间、最小连接数 等一样,Druid 数据源同理能够进行设置;

配置 Druid web 监控 filter(WebStatFilter): 这个过滤器的作用就是统计 web 利用申请中所有的数据库信息,比方 收回的 sql 语句,sql 执行的工夫、申请次数、申请的 url 地址、以及 seesion 监控、数据库表的拜访次数 等等。

配置 Druid 后盾治理 Servlet(StatViewServlet): Druid 数据源具备监控的性能,并提供了一个 web 界面不便用户查看,相似装置 路由器 时,人家也提供了一个默认的 web 页面;须要设置 Druid 的后盾治理页面的属性,比方 登录账号、明码 等;

留神:

Druid Spring Boot Starter 配置属性的名称齐全遵循 Druid,能够通过 Spring Boot 配置文件来配置 Druid 数据库连接池和监控,如果没有配置则应用默认值。

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?serverTimezone=Asia/Shanghai
    platform: mysql                               # 数据库类型
    type: com.alibaba.druid.pool.DruidDataSource  # 指定数据源类型
    ########## 连接池 配置 ##########
    druid:
      # 配置初始化大小、最小、最大
      initial-size: 5
      minIdle: 10
      max-active: 20
      # 配置获取连贯期待超时的工夫(单位:毫秒)
      max-wait: 60000
      # 配置距离多久才进行一次检测,检测须要敞开的闲暇连贯,单位是毫秒
      time-between-eviction-runs-millis: 2000
      # 配置一个连贯在池中最小生存的工夫,单位是毫秒
      min-evictable-idle-time-millis: 600000
      max-evictable-idle-time-millis: 900000
      # 用来测试连贯是否可用的 SQL 语句, 默认值每种数据库都不雷同, 这是 mysql
      validationQuery: select 1
      # 利用向连接池申请连贯,并且 testOnBorrow 为 false 时,连接池将会判断连贯是否处于闲暇状态,如果是,则验证这条连贯是否可用
      testWhileIdle: true
      # 如果为 true,默认是 false,利用向连接池申请连贯时,连接池会判断这条连贯是否是可用的
      testOnBorrow: false
      # 如果为 true(默认 false),当利用应用完连贯,连接池回收连贯的时候会判断该连贯是否还可用
      testOnReturn: false
      # 是否缓存 preparedStatement,也就是 PSCache。PSCache 对反对游标的数据库性能晋升微小,比如说 oracle
      poolPreparedStatements: true
      # 要启用 PSCache,必须配置大于 0,当大于 0 时,poolPreparedStatements 主动触发批改为 true,# 在 Druid 中,不会存在 Oracle 下 PSCache 占用内存过多的问题,# 能够把这个数值配置大一些,比如说 100
      maxOpenPreparedStatements: 20
      # 连接池中的 minIdle 数量以内的连贯,闲暇工夫超过 minEvictableIdleTimeMillis,则会执行 keepAlive 操作
      keepAlive: true
      # Spring 监控,利用 aop 对指定接口的执行工夫,jdbc 数进行记录
      aop-patterns: "com.springboot.template.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
        # 日志监控,应用 slf4j 进行日志输入
        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:
        enabled: true                   # 启动 StatFilter
        url-pattern: /*                 # 过滤所有 url
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" # 排除一些不必要的 url
        session-stat-enable: true       # 开启 session 统计性能
        session-stat-max-count: 1000    # session 的最大个数, 默认 100
      ########## 配置 StatViewServlet(监控页面),用于展现 Druid 的统计信息 ##########
      stat-view-servlet:
        enabled: true                   # 启用 StatViewServlet
        url-pattern: /druid/*           # 拜访内置监控页面的门路,内置监控页面的首页是 /druid/index.html
        reset-enable: false              # 不容许清空统计数据, 从新计算
        login-username: root            # 配置监控页面拜访明码
        login-password: 123
        allow: 127.0.0.1           # 容许拜访的地址,如果 allow 没有配置或者为空,则容许所有拜访
        deny:                                        # 回绝拜访的地址,deny 优先于 allow,如果在 deny 列表中,就算在 allow 列表中,也会被回绝

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

3.1 如何配置 Filter

能够通过 spring.datasource.druid.filters=stat,wall,log4j ...的形式来启用相应的内置 Filter,不过这些 Filter 都是默认配置。如果默认配置不能满足需要,能够放弃这种形式,通过配置文件来配置 Filter,上面是例子。

# 配置 StatFilter 
spring.datasource.druid.filter.stat.enabled=true
spring.datasource.druid.filter.stat.db-type=h2
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=2000

# 配置 WallFilter 
spring.datasource.druid.filter.wall.enabled=true
spring.datasource.druid.filter.wall.db-type=h2
spring.datasource.druid.filter.wall.config.delete-allow=false
spring.datasource.druid.filter.wall.config.drop-table-allow=false

目前为以下 Filter 提供了配置反对,依据(spring.datasource.druid.filter.*)进行配置。

  • StatFilter
  • WallFilter
  • ConfigFilter
  • EncodingConvertFilter
  • Slf4jLogFilter
  • Log4jFilter
  • Log4j2Filter
  • CommonsLogFilter

不想应用内置的 Filters,要想使自定义 Filter 配置失效须要将对应 Filter 的 enabled 设置为 true,Druid Spring Boot Starter 默认禁用 StatFilter,能够将其 enabled 设置为 true 来启用它。

4 监控页面

(1)启动我的项目后,拜访 /druid/login.html 来到登录页面,输出用户名明码登录

(2)数据源页面 是以后 DataSource 配置的根本信息,上述配置的 Filter 能够在外面找到,如果没有配置 Filter(一些信息会无奈统计,例如“SQL 监控”,会无奈获取 JDBC 相干的 SQL 执行信息)

(3)SQL 监控页面,统计了所有 SQL 语句的执行状况

(4)URL 监控页面,统计了所有 Controller 接口的拜访以及执行状况

(5)Spring 监控页面,利用 aop 对指定接口的执行工夫,jdbc 数进行记录

(6)SQL 防火墙页面

druid 提供了黑白名单的拜访,能够分明的看到 sql 防护状况。

(7)Session 监控页面

能够看到以后的 session 情况,创立工夫、最初沉闷工夫、申请次数、申请工夫等具体参数。

(8)JSONAPI 页面

通过 api 的模式拜访 Druid 的监控接口,api 接口返回 Json 模式数据。

5 sql 监控

配置 Druid web 监控 filter(WebStatFilter)这个过滤器,作用就是统计 web 利用申请中所有的数据库信息,比方 收回的 sql 语句,sql 执行的工夫、申请次数、申请的 url 地址、以及 seesion 监控、数据库表的拜访次数 等等。

spring:
  datasource:
    druid:
      ########## 配置 WebStatFilter,用于采集 web 关联监控的数据 ##########
      web-stat-filter:
        enabled: true                   # 启动 StatFilter
        url-pattern: /*                 # 过滤所有 url
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" # 排除一些不必要的 url
        session-stat-enable: true       # 开启 session 统计性能
        session-stat-max-count: 1000    # session 的最大个数, 默认 100

6 慢 sql 记录

有时候,零碎中有些 SQL 执行很慢,咱们心愿应用日志记录下来,能够开启 Druid 的慢 SQL 记录性能

spring:
  datasource:
    druid:
      filter:
        stat:
          enabled: true         # 开启 DruidDataSource 状态监控
          db-type: mysql        # 数据库的类型
          log-slow-sql: true    # 开启慢 SQL 记录性能
          slow-sql-millis: 2000 # 默认 3000 毫秒,这里超过 2s,就是慢,记录到日志

启动后,如果遇到执行慢的 SQL,便会输入到日志中

7 spring 监控

拜访之后 spring 监控默认是没有数据的;

这须要导入 SprngBoot 的 AOP 的 Starter

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

须要在 application.yml 配置:

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

 spring.datasource.druid.aop-patterns="com.springboot.template.dao.*"

8 去 Ad(广告)

拜访监控页面的时候,你可能会在页面底部(footer)看到阿里巴巴的广告

起因:引入的 druid 的 jar 包中的 common.js(外面有一段 js 代码是给页面的 footer 追加广告的)

如果想去掉,有两种形式:

(1) 间接手动正文这段代码

如果是应用 Maven,间接到本地仓库中,查找这个 jar 包

要正文的代码:

// this.buildFooter();

common.js 的地位:

com/alibaba/druid/1.1.23/druid-1.1.23.jar!/support/http/resources/js/common.js

(2) 应用过滤器过滤

注册一个过滤器,过滤 common.js 的申请,应用正则表达式替换相干的广告内容

@Configuration
@ConditionalOnWebApplication
@AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled",
havingValue = "true", matchIfMissing = true)
public class RemoveDruidAdConfig {

    /**
    * 办法名: removeDruidAdFilterRegistrationBean
    * 办法形容 除去页面底部的广告
    * @param properties com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties
    * @return org.springframework.boot.web.servlet.FilterRegistrationBean
    */
    @Bean
    public FilterRegistrationBean removeDruidAdFilterRegistrationBean(DruidStatProperties properties) {

        // 获取 web 监控页面的参数
        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
        // 提取 common.js 的配置门路
        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");

        final String filePath = "support/http/resources/js/common.js";

        // 创立 filter 进行过滤
        Filter filter = new Filter() {
            @Override
            public void init(FilterConfig filterConfig) throws ServletException {}

            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {chain.doFilter(request, response);
                // 重置缓冲区,响应头不会被重置
                response.resetBuffer();
                // 获取 common.js
                String text = Utils.readFromResource(filePath);
                // 正则替换 banner, 除去底部的广告信息
                text = text.replaceAll("<a.*?banner\"></a><br/>","");
                text = text.replaceAll("powered.*?shrek.wang</a>", "");
                response.getWriter().write(text);
            }

            @Override
            public void destroy() {}
        };

        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
}

两种形式都能够,倡议应用的是第一种,从本源解决

9 获取 Druid 的监控数据

Druid 的监控数据能够在 开启 StatFilter 后,通过 DruidStatManagerFacade 进行获取;

DruidStatManagerFacade#getDataSourceStatDataList 该办法能够获取所有数据源的监控数据,

除此之外 DruidStatManagerFacade 还提供了一些其余办法,能够按需抉择应用。

@RestController
@RequestMapping(value = "/druid")
public class DruidStatController {@GetMapping("/stat")
    public Object druidStat(){
        // 获取数据源的监控数据
        return DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
    }
}

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0