1. 什么是Druid连接池

Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。
虽然 HikariCP 的速度稍快,但是,Druid能够提供强大的监控和扩展功能,也是阿里巴巴的开源项目。
Spring Boot 2.x 默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源。

  • stat:Druid内置提供一个StatFilter,用于统计监控信息。

  • wall:Druid防御SQL注入攻击的WallFilter就是通过Druid的SQL Parser分析。Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。

  • log4j2:这个就是 日志记录的功能,可以把sql语句打印到log4j2 供排查问题。

    2. 添加依赖

    ```xml

    com.alibaba druid-spring-boot-starter ${com.alibaba.druid.version}

org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.3 com.zaxxer HikariCP

  1. <a name="cZ9Gm"></a>
  2. # 3. 配置相关属性
  3. 1. **配置Druid数据源(连接池):** 如同以前 c3p0、dbcp 数据源可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等一样,Druid 数据源同理可以进行设置;
  4. 1. **配置 Druid web 监控 filter(WebStatFilter):** 这个过滤器的作用就是统计 web 应用请求中所有的数据库信息,比如 发出的 sql 语句,sql 执行的时间、请求次数、请求的 url 地址、以及seesion 监控、数据库表的访问次数 等等。
  5. 1. **配置 Druid 后台管理 Servlet(StatViewServlet):** Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装 路由器 时,人家也提供了一个默认的 web 页面;需要设置 Druid 的后台管理页面的属性,比如 登录账号、密码 等;
  6. Druid Spring Boot Starter 配置属性的名称完全遵照 Druid,可以通过 Spring Boot 配置文件来配置Druid数据库连接池和监控,如果没有配置则使用默认值。
  7. ```java
  8. # 服務器HTTP端口,默認:8080
  9. server.port=8088
  10. # 應用程序的上下文路徑
  11. server.servlet.context-path=/
  12. # 會話超時。 如果未指定持續時間後綴,則將使用秒。默認30m
  13. server.servlet.session.timeout=30m
  14. # 用於解碼URI的字符編碼,默認:UTF-8
  15. server.tomcat.uri-encoding=UTF-8
  16. # Tomcat基本目錄。 如果未指定,則使用一個臨時目錄。
  17. server.tomcat.basedir=target/temp
  18. # 服務器在任何給定時間接受和處理的最大連接數。 一旦達到限制,操作系統仍然可以基於“ acceptCount”屬性接受連接。默認 8192
  19. server.tomcat.max-connections=2000
  20. # 工作線程的最大數量。默認:200
  21. server.tomcat.threads.max=200
  22. # 連接器在接受連接後將等待呈現請求URI行的時間。
  23. server.tomcat.connection-timeout=8000
  24. #datasource
  25. # 連接資料庫的url,不同資料庫不一樣。
  26. spring.datasource.druid.url=jdbc:postgresql://10.213.133.130:5432/zbdb
  27. # 連接資料庫的用戶名
  28. spring.datasource.druid.username=lgszz
  29. # 連接資料庫的密碼。
  30. spring.datasource.druid.password=lgszz.2020
  31. # druid 配置
  32. # 要使用的連接池實現的完全限定名稱。 默認情況下,它是從類路徑中自動檢測到的。
  33. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
  34. # 初始化時建立物理連接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時
  35. spring.datasource.druid.initial-size=10
  36. # 最大連接池數量
  37. spring.datasource.druid.max-active=50
  38. # 最小連接池數量
  39. spring.datasource.druid.min-idle=10
  40. # 獲取連接時最大等待時間,單位毫秒。配置了maxWait之後,缺省啟用公平鎖,併發效率會有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
  41. spring.datasource.druid.max-wait=3000
  42. # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒
  43. spring.datasource.druid.time-between-eviction-runs-millis=60000
  44. # 配置一個連接在池中最小生存的時間,單位是毫秒
  45. spring.datasource.druid.min-evictable-idle-time-millis=300000
  46. # 用來檢測連接是否有效的sql,要求是一個查詢語句,常用select 'x'。如果validation-query為null,test-on-borrow、test-on-return、test-while-idle都不會起作用。
  47. spring.datasource.druid.validation-query=SELECT 1
  48. # 建議配置為true,不影響性能,並且保證安全性。申請連接的時候檢測,如果閒置時間大於time-between-eviction-runs-millis,執行validation-query檢測連接是否有效。默認爲false
  49. spring.datasource.druid.test-while-idle=true
  50. # 申請連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能。默認爲true
  51. spring.datasource.druid.test-on-borrow=true
  52. # 歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能。默認爲false
  53. spring.datasource.druid.test-on-return=false
  54. # 是否緩存preparedStatement,也就是PSCache。PSCache對支援游標的資料庫性能提升巨大,比如說oracle。在mysql下建議關閉。
  55. spring.datasource.druid.pool-prepared-statements=true
  56. # 要啟用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改為true。
  57. spring.datasource.druid.max-pool-prepared-statement-per-connection-size=50
  58. # 連接池中的minIdle數量以內的連接,閒置時間超過minEvictableIdleTimeMillis,則會執行keepAlive操作
  59. #spring.datasource.druid.keep-alive=true
  60. # Spring 監控,利用aop 對指定介面的執行時間,jdbc數進行記錄
  61. #spring.datasource.druid.aop-patterns="com.springboot.template.dao.*"
  62. ########### 啟用內置篩檢程式(第一個 stat必須,否則監控不到SQL)##########
  63. # 配置監控統計攔截的filters,去掉後監控介面SQL無法進行統計,屬性類型是字串,通過別名的方式配置擴展外掛程式,常用的外掛程式有:監控統計用的filter:stat,日誌用的filter:log4j,防禦sql注入的filter:wall
  64. spring.datasource.druid.filters=config,stat,slf4j,wall
  65. # 開啟druid datasource 的狀態監控
  66. spring.datasource.druid.filter.stat.enabled=true
  67. # 開啟慢sql監控,超過2s 就認為是慢sql,記錄到日誌中
  68. spring.datasource.druid.filter.stat.log-slow-sql=true
  69. spring.datasource.druid.filter.stat.slow-sql-millis=2000
  70. # 配置 connection-properties,啓用加密
  71. #spring.datasource.druid.connection-properties=config.decrypt=true;
  72. # 啓用ConfigFilter
  73. #spring.datasource.druid.filter.config.enabled=true
  74. ########## druid連接池監控 ##########
  75. ########## 配置StatViewServlet(監控頁面),用於展示Druid的統計信息 ##########
  76. # 啓用StatViewServlet
  77. spring.datasource.druid.stat-view-servlet.enabled=true
  78. # 訪問內置監控頁面的路徑,內置監控頁面的首頁是/druid/index.html
  79. spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
  80. # 不允許清空統計資料,重新計算
  81. spring.datasource.druid.stat-view-servlet.reset-enable=false
  82. # 配置監控頁面訪問賬號
  83. spring.datasource.druid.stat-view-servlet.login-username=admin
  84. # 配置監控頁面訪問密碼
  85. spring.datasource.druid.stat-view-servlet.login-password=admin
  86. # 白名單,允許訪問的位址,如果allow沒有配置或者為空,則允許所有訪問
  87. spring.datasource.druid.stat-view-servlet.allow=
  88. # 黑名單,拒絕訪問的位址,deny優先於allow,如果在deny列表中,就算在allow列表中,也會被拒絕
  89. spring.datasource.druid.stat-view-servlet.deny=
  90. ########## 配置WebStatFilter,用於採集web關聯監控的數據 ##########
  91. # 啓用StatFilter
  92. spring.datasource.druid.web-stat-filter.enabled=true
  93. # 過濾所有url
  94. spring.datasource.druid.web-stat-filter.url-pattern=/*
  95. # 排除一些不必要的url
  96. spring.datasource.druid.web-stat-filter.exclusions=*.gif,*.png,*.jpg,*.html,*.js,*.css,*.ico,/druid/*
  97. # 開啓session統計功能
  98. spring.datasource.druid.web-stat-filter.session-stat-enable=true
  99. # session的最大個數,默認1000
  100. spring.datasource.druid.web-stat-filter.session-stat-max-count=1000

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

3.1 如何配置 Filter

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

  1. # 配置StatFilter
  2. spring.datasource.druid.filter.stat.enabled=true
  3. spring.datasource.druid.filter.stat.db-type=h2
  4. spring.datasource.druid.filter.stat.log-slow-sql=true
  5. spring.datasource.druid.filter.stat.slow-sql-millis=2000
  6. # 配置WallFilter
  7. spring.datasource.druid.filter.wall.enabled=true
  8. spring.datasource.druid.filter.wall.db-type=h2
  9. spring.datasource.druid.filter.wall.config.delete-allow=false
  10. 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 监控、数据库表的访问次数 等等。

    1. ########## 配置WebStatFilter,用於採集web關聯監控的數據 ##########
    2. # 啓用StatFilter
    3. spring.datasource.druid.web-stat-filter.enabled=true
    4. # 過濾所有url
    5. spring.datasource.druid.web-stat-filter.url-pattern=/*
    6. # 排除一些不必要的url
    7. spring.datasource.druid.web-stat-filter.exclusions=*.gif,*.png,*.jpg,*.html,*.js,*.css,*.ico,/druid/*
    8. # 開啓session統計功能
    9. spring.datasource.druid.web-stat-filter.session-stat-enable=true
    10. # session的最大個數,默認1000
    11. spring.datasource.druid.web-stat-filter.session-stat-max-count=1000

    6. 慢sql记录

    有时候,系统中有些SQL执行很慢,我们希望使用日志记录下来,可以开启Druid的慢SQL记录功能

    1. # 開啟druid datasource 的狀態監控
    2. spring.datasource.druid.filter.stat.enabled=true
    3. # 開啟慢sql監控,超過2s 就認為是慢sql,記錄到日誌中
    4. spring.datasource.druid.filter.stat.log-slow-sql=true
    5. spring.datasource.druid.filter.stat.slow-sql-millis=2000

    7. spring 监控

    访问之后spring监控默认是没有数据的;
    这需要导入SprngBoot的AOP的Starter

    1. <!--SpringBoot 的aop 模块-->
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-aop</artifactId>
    5. </dependency>

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

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

    8. 去 Ad(广告)

    访问监控页面的时候,你可能会在页面底部(footer)看到阿里巴巴的广告
    原因:引入的druid的jar包中的common.js(里面有一段js代码是给页面的footer追加广告的)
    如果想去掉,有两种方式:

    8.1 直接手动注释这段代码

    如果是使用Maven,直接到本地仓库中,查找这个jar包
    要注释的代码:

    1. // this.buildFooter();

    common.js的位置:

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

    8.2 使用过滤器过滤

    注册一个过滤器,过滤common.js的请求,使用正则表达式替换相关的广告内容 ```java @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() {

      1. @Override
      2. public void init(FilterConfig filterConfig) throws ServletException {}
      3. @Override
      4. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      5. chain.doFilter(request, response);
      6. // 重置缓冲区,响应头不会被重置
      7. response.resetBuffer();
      8. // 获取common.js
      9. String text = Utils.readFromResource(filePath);
      10. // 正则替换banner, 除去底部的广告信息
      11. text = text.replaceAll("<a.*?banner\"></a><br/>", "");
      12. text = text.replaceAll("powered.*?shrek.wang</a>", "");
      13. response.getWriter().write(text);
      14. }
      15. @Override
      16. public void destroy() {}

      };

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

  1. 两种方式都可以,建议使用的是第一种,从根源解决
  2. <a name="d6L8V"></a>
  3. # 9. 获取 Druid 的监控数据
  4. Druid 的监控数据可以在 开启 StatFilter 后,通过 DruidStatManagerFacade 进行获取;<br />DruidStatManagerFacade#getDataSourceStatDataList 该方法可以获取所有数据源的监控数据,除此之外 DruidStatManagerFacade 还提供了一些其他方法,可以按需选择使用。
  5. ```java
  6. @RestController
  7. @RequestMapping(value = "/druid")
  8. public class DruidStatController {
  9. @GetMapping("/stat")
  10. public Object druidStat(){
  11. // 获取数据源的监控数据
  12. return DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
  13. }
  14. }