欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Druid的sql监控页面没有数据

程序员文章站 2022-07-12 12:56:40
...

1.本人使用各框架版本

springboot:2.2.2
druid:1.1.18

druid配置类:

package com.learn.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 
 */
@Configuration
public class DruidConfiguration {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }
    /**
     * 配置Druid的监控
     * 1.配置一个管理后台的servlet
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean servletRegistrationBean =
                new ServletRegistrationBean(new StatViewServlet(), "/druid/*");

        Map<String, String> initParams = new HashMap<>(16);
        initParams.put("loginUsername", "admin");
        initParams.put("loginPassword" , "123");
        //默认允许所有访问
        initParams.put("allow" , "");
        initParams.put("deny" , "192.168.1.103");
        servletRegistrationBean.setInitParameters(initParams);

        return servletRegistrationBean;
    }

    /**
     * 2.配置一个web监控的filter
     * @return
     */
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        Map<String, String> initParams = new HashMap<>(16);
        initParams.put("exclusions", "*.js,*.css,*.png,*.jpg,*.ico,/druid/*");
        filterRegistrationBean.setInitParameters(initParams);
        return filterRegistrationBean;
    }
}

2.确认进行了sql数据查询

3.表面原因:数据源页面filter类为空

4.根本原因

第一种情况:filter方法没添加@Bean

检查@Bean是否添加,一开始是因为这个,加了之后发现sql监控还是没有数据

	@Bean
    public FilterRegistrationBean webStatFilter(){

第二种情况:spring.datasource.filters没配置或配置错误

解决办法:

  1. 第一种方法:通过百度,发现加上虚拟机参数也可以(经测试,发现第二个参数可有可无),之后会在数据源页面发现filter类为com.alibaba.druid.filter.stat.MergeStatFilter,并且sql监控页面有了数据。
-Ddruid.filters=mergeStat -Ddruid.useGlobalDataSourceStat=true
  1. 第二种方法:配置文件中配置spring.datasource.filters=stat,wall,log4j之后,又踩了一个坑,启动发现org.apache.log4j.Priority,apache下的是log4j2的实现类,而该版本druid需要的是log4j。
    现在两个选择:
  • (1)删掉log4j
  • (2)导入log4j依赖
Failed to bind properties under 'spring.datasource' to javax.sql.DataSource:

    Property: spring.datasource.filters
    Value: stat,wall,log4j
    Origin: class path resource [application.yml]:21:14
    Reason: org.apache.log4j.Priority

当然是选择后者,不过这里要注意了,通过查看springboot2.2.2的logging依赖,发现只有log4j-to-slf4j,(springboot1.x.x的logging会依赖log4j-over-slf4j)
关于log日志,详细查看slf4j官方文档

Druid的sql监控页面没有数据

log4j-over-slf4j:Log4j implemented over SLF4J log4j-to-slf4:Apache
log4j-to-slf4j:SLF4J Adapter,The Apache Log4j binding between Log4j 2 API and SLF4J.
log4j-to-slf4j本人还是不太明白,有清楚的小伙伴欢迎留言

总之,引入log4j依赖的时候肯定不推荐直接引用log4j,这样会给一个springboot系统产生两套日志系统

	<dependency>
		<groupId>log4j</groupId>
		<artifactId>log4j</artifactId>
		<version></version>
	</dependency>

而推荐引用log4j-over-slf4j,这样还是在slf4j这个日志门户的框架下,底层日志实现还是springboot默认使用的logback

	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>log4j-over-slf4j</artifactId>
	</dependency>

完整配置:

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
    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,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

最后,完美解决问题,数据源页面的filter类为com.alibaba.druid.filter.stat.StatFilter,com.alibaba.druid.wall.WallFilter,com.alibaba.druid.filter.logging.Log4jFilter共3个
记得去掉之前配置的虚拟机参数,否则filter加上之前的一共会有4个,最重要的是访问一次数据请求会进行2次数据查询!
=========================如有错误,欢迎指正===========================

相关标签: SpringBoot