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();
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM