spriongboot与数据源的整合以及SQL监控

Posted Lee_Sung

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spriongboot与数据源的整合以及SQL监控相关的知识,希望对你有一定的参考价值。

spriongboot与数据源的整合

在Java中,数据源就是javax.sql.DataSource,DataSource有不同的实现。数据源包含连接池和连接池管理两个部分,习惯上也把 DataSource 称为连接池。常见的数据库连接池有Druid、BoneCP、DBCP、C3P0等。

C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

Druid是阿里开源的一个数据源,他不但包含连接池,还包含一个ProxyDriver,一系列内置的JDBC组件库,一个 SQL Parser。Druid兼容常见的关系型数据库,并且针对Oracle和mysql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。

C3P0或者Druid与SpringBoot整合基本有properties文件配置的方式和JavaBean配置的方式(这是因为Springboot对这两种连接池的天然支持),按照springboot简化配置文件的思想,应该使用注解配置比较合适(但是我发现其实使用properties文件配置更方便一些,见仁见智,哪个方便用哪个)。下面记录一下在Springboot中整合Druid的方式。

1.application.properties文件配置的方式

POM 依赖

<!--mysql相关-->
 <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <scope>runtime</scope>
</dependency>
<dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>druid-spring-boot-starter</artifactId>
       <version>1.1.9</version>
</dependency>

application.properties 配置(yml方式可自行根据该文件配置)
此处可参考源码https://github.com/alibaba/druid和文档https://github.com/alibaba/druid/blob/master/druid-spring-boot-starter/README.md

#####################################  数据源,使用阿里巴巴的druid数据源  ########################################
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.username=username
spring.datasource.druid.password=password
spring.datasource.druid.url=jdbc:mysql://localhost:3306/db_name?useSSL=false&useUnicode=true&characterEncoding=utf8
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
####################################### 连接池配置
# 初始化大小,最小,最大
spring.datasource.druid.initialSize=5
spring.datasource.druid.minIdle=5
spring.datasource.druid.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.druid.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.druid.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
#spring.datasource.useGlobalDataSourceStat=true

#以下配置,IDEA可能会报检测不到的警告,但是实际可用
#############################################    Druid WebStatFilter配置
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.gif,*.png,*.jpg,*.html,*.js,*.css,*.ico,/druid/*
#############################################    Druid StatViewServlet配置
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
spring.datasource.druid.stat-view-servlet.allow=
spring.datasource.druid.stat-view-servlet.deny=

2. JavaBean的配置方式

POM依赖参考上面,不再赘述。
properties文件中

#####################################  数据源,使用阿里巴巴的druid数据源  ########################################
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.username=username
spring.datasource.druid.password=password
spring.datasource.druid.url=jdbc:mysql://localhost:3306/db_name?useSSL=false&useUnicode=true&characterEncoding=utf8
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
####################################### 连接池配置
# 初始化大小,最小,最大
spring.datasource.druid.initialSize=5
spring.datasource.druid.minIdle=5
spring.datasource.druid.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.druid.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.druid.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
#spring.datasource.useGlobalDataSourceStat=true

配置Druid(这里如果properties文件中的配置不能读取,需要以这种方式)
DruidConfig.Java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;

/** druid配置类
 * @description:  自动读取 application.properties文件中以spring.datasource开头的信息,将DataSource对象的实现类变为了DruidDataSource对象。
 */
//@Configuration
public class DruidConfig 
	/* 或者直接关联properties文件中的相关属性,手动注入到DataSource中。
    @Value("$spring.datasource.url")
    private String dbUrl;
    @Value("$spring.datasource.username")
    private String username;
    @Value("$spring.datasource.password")
    private String password;
    @Value("$spring.datasource.driverClassName")
    private String driverClassName;
    @Value("$spring.datasource.initialSize")
    private int initialSize;
    @Value("$spring.datasource.minIdle")
    private int minIdle;
    @Value("$spring.datasource.maxActive")
    private int maxActive;
    @Value("$spring.datasource.maxWait")
    private int maxWait;
    @Value("$spring.datasource.timeBetweenEvictionRunsMillis")
    private int timeBetweenEvictionRunsMillis;
    @Value("$spring.datasource.minEvictableIdleTimeMillis")
    private int minEvictableIdleTimeMillis;
    @Value("$spring.datasource.validationQuery")
    private String validationQuery;
    @Value("$spring.datasource.testWhileIdle")
    private boolean testWhileIdle;
    @Value("$spring.datasource.testOnBorrow")
    private boolean testOnBorrow;
    @Value("$spring.datasource.testOnReturn")
    private boolean testOnReturn;
    @Value("$spring.datasource.poolPreparedStatements")
    private boolean poolPreparedStatements;
    @Value("$spring.datasource.maxPoolPreparedStatementPerConnectionSize")
    private int maxPoolPreparedStatementPerConnectionSize;
    @Value("$spring.datasource.filters")
    private String filters;
    @Value("$spring.datasource.connectionProperties")
    private String connectionProperties;
    @Value("$spring.datasource.useGlobalDataSourceStat")
    private boolean useGlobalDataSourceStat;
	*/
    
    /**
     * @param: []
     * @return: javax.sql.DataSource
     * 读取属性的方式,引入application.properties文件中以spring.datasource开头的信息,因此需要在application.properties文件中配置相关信息。
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() 
        DruidDataSource druidDataSource = new DruidDataSource();
        /* 如果手动注入,应该不需要加@ConfigurationProperties(prefix = "spring.datasource")注解,未测试
        druidDataSource.setUrl(this.dbUrl);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        druidDataSource.setDriverClassName(driverClassName);
        //configuration
        druidDataSource.setInitialSize(initialSize);
        druidDataSource.setMinIdle(minIdle);
        druidDataSource.setMaxActive(maxActive);
        druidDataSource.setMaxWait(maxWait);
        druidDataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        druidDataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        druidDataSource.setValidationQuery(validationQuery);
        druidDataSource.setTestWhileIdle(testWhileIdle);
        druidDataSource.setTestOnBorrow(testOnBorrow);
        druidDataSource.setTestOnReturn(testOnReturn);
        druidDataSource.setPoolPreparedStatements(poolPreparedStatements);
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        druidDataSource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
        try 
            druidDataSource.setFilters(filters);
         catch (SQLException e) 
            System.err.println("druid configuration initialization filter: " + e);
        
        druidDataSource.setConnectionProperties(connectionProperties);
		*/
        return druidDataSource;
    

配置监控器
DruidStatViewServlet.Java

import com.alibaba.druid.support.http.StatViewServlet;

import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

@WebServlet(urlPatterns = "/druid/*",
        initParams = @WebInitParam(name = "allow", value = "127.0.0.1"),// IP白名单 (没有配置或者为空,则允许所有访问)
                @WebInitParam(name = "deny", value = "192.168.0.0"), // IP黑名单 (存在共同时,deny优先于allow)
                @WebInitParam(name = "loginUsername", value = "admin"),// druid监控页面登陆用户名
                @WebInitParam(name = "loginPassword", value = "admin"),// druid监控页面登陆密码
                @WebInitParam(name = "resetEnable", value = "false"))// 禁用HTML页面上的“Reset All”功能)

public class DruidStatViewServlet extends StatViewServlet 
    private static final long serialVersionUID = 1L;

配置过滤规则
DruidStatViewServlet.Java

import com.alibaba.druid.support.http.WebStatFilter;

import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

/**
 * @description: 配置druid过滤规则,监控所有的页面,排除以下配置的文件
 * 配置文件里配置过了,此处不使用
 */
@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*",
        initParams = 
                @WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略资源
        )
public class DruidStatFilter extends WebStatFilter 


访问http://localhost:8080/druid,并使用配置的druid用户名和密码登陆,即可进行sql监控等操作。

在我这边配置时,其实不用Javabean的方式就可以,appliacation.properties中配置的内容都可以被加载并生效。当采用JavaBean方式时其实可以在proerties文中自定义属性前缀,即在Bean中用@Value()注解标识properties中的属性,然后手动注册即可。因此proerties文件中配置的数据源可以给任意一个需要的地方直接拿用的,其实不需要再用javaBeanConfig了,一般javaBeanConfig是为了将DataSource数据源注入到jdbcTemplate(或者其他需要注入数据源的中间件等)中的。

以上是关于spriongboot与数据源的整合以及SQL监控的主要内容,如果未能解决你的问题,请参考以下文章

通用财经数据传输与监控平台1.0(泛型,接口与基类,Sql,Ibatis,Awt,Swing)

Spring Boot 整合 Mybatis 实现 Druid 多数据源详解

虚拟化监控管理工具如何选择

Zabbix与ELK整合实现对日志数据的实时监控

Springboot整合Druid监控

虚拟化监管工具该如何选择