SpringBoot中使用 Druid 数据库连接池, 后台SQL监控无效

首先说下环境和配置, 问题

环境
SpringBoot: 2.3.4.RELEASE
druid-spring-boot-starter: 1.1.22

配置

  • yaml文件配置
datasource:
    url: jdbc:mysql://localhost:3306/testdb
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      # 数据源的其他配置
      initialSize: 5
      minIdle: 5
      maxActive: 20
      maxWait: 60000
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      # 配置监控统计拦截的 filters,去掉后监控界面 sql 无法统计,'wall'用于防火墙
      filters: stat,wall
      maxPoolPreparedStatementPerConnectionSize: 20
      useGlobalDataSourceStat: true
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  • DruidConfiguration 配置类
@Configuration
public class DruidConfiguration {

    /**
     * 配置数据源信息
     * @return 数据源
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() throws SQLException {
        DruidDataSource dds = new DruidDataSource();
        dds.setDbType("mysql");//mysql必须小写
        return dds;
    }

    @Bean
    public ServletRegistrationBean<StatViewServlet> servletRegistrationBean(){
        ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
        // IP白名单
        servletRegistrationBean.addInitParameter("allow","127.0.0.1");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername","admin");
        servletRegistrationBean.addInitParameter("loginPassword","admin");
        //是否能够重置数据
        servletRegistrationBean.addInitParameter("resetEnable","false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean<WebStatFilter> statFilter(){
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>(new WebStatFilter());
        //添加过滤规则
        filterRegistrationBean.addUrlPatterns("/*");
        //忽略过滤的格式
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

问题
可以获取数据, 后台有SQL输出
但是SQL监控页面就死活不出现SQL语句的监控

解决办法有两

第一种, 修改yaml文件

其实很简单, 就是把所有 druid 为根节点的配置项往上提, 也就是去掉 druid 节点

datasource:
    url: jdbc:mysql://localhost:3306/xinguan
    username: root
    password: qkm19981013
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    # 数据源的其他配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    # 配置监控统计拦截的 filters,去掉后监控界面 sql 无法统计,'wall'用于防火墙
    filters: stat,wall
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

这样就可以监控到SQL语句了
监控SQL语句成功
但是这样会有个问题(强迫症患者, 就是 yaml 文件有好多警告, 看着不爽, 我就是 >_<), 如图
满屏警告

第二种, 修改yaml文件和配置类

  • yaml 文件
datasource:
    url: jdbc:mysql://localhost:3306/xinguan
    username: root
    password: qkm19981013
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

其实也就是将 其他的配置放到配置类中

  • DruidConfiguration 配置类
@Configuration
public class DruidConfiguration {

    /**
     * 配置数据源信息
     * @return 数据源
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() throws SQLException {
        DruidDataSource dds = new DruidDataSource();
        dds.setInitialSize(5);                                  /* 初始化时建立物理连接的个数 */
        dds.setMaxActive(20);                                   /* 最大连接池数量 */
        dds.setMaxWait(60000);                                  /* 获取连接时最大等待时间,单位毫秒 */
        dds.setMinIdle(8);                                      /* 最小连接池数量 */
        dds.setTimeBetweenEvictionRunsMillis(60000);            /* Destroy线程会检测连接的间隔时间 */
        dds.setMinEvictableIdleTimeMillis(300000);              /* 连接保持空闲而不被驱逐的最小时间 */
        dds.setValidationQuery("SELECT 1 FROM DUAL");           /* 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 */
        dds.setTestWhileIdle(true);                             /* 建议配置为true,不影响性能,并且保证安全性 */
        dds.setTestOnBorrow(false);                             /* 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 */
        dds.setTestOnReturn(false);                             /* 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 */
        dds.setPoolPreparedStatements(false);                   /* 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭 */
        dds.setFilters("stat,wall");                            /* 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:监控统计用的filter:stat, 日志用的filter:log4j, 防御sql注入的filter:wall */
        dds.setMaxPoolPreparedStatementPerConnectionSize(50);   /* 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 */
        dds.setUseGlobalDataSourceStat(true);
        Properties properties = new Properties();
        properties.setProperty("druid.stat.mergeSql", "true");
        properties.setProperty("druid.stat.slowSqlMillis", "100");
        dds.setConnectProperties(properties);
        dds.setDbType("mysql");//mysql必须小写
        return dds;
    }

    @Bean
    public ServletRegistrationBean<StatViewServlet> servletRegistrationBean(){
        ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
        // IP白名单
        servletRegistrationBean.addInitParameter("allow","127.0.0.1");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername","admin");
        servletRegistrationBean.addInitParameter("loginPassword","admin");
        //是否能够重置数据
        servletRegistrationBean.addInitParameter("resetEnable","false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean<WebStatFilter> statFilter(){
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>(new WebStatFilter());
        //添加过滤规则
        filterRegistrationBean.addUrlPatterns("/*");
        //忽略过滤的格式
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

这样的话也可以监控到 SQL 语句, 此篇结束, 谢谢啦, 如果解决了您的问题, 帮忙给个赞哦!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值