SpringBoot-Druid

384 阅读3分钟

Druid

什么是Druid

  1. Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。

  2. Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。

  3. Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。

  4. Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

  5. Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。

Druid的使用

前期准备工作

  1. 新建一个SpringBoot项目时,记得勾选 spring webJDBC APIMySQL Driver.
  2. 在pom.xml配置文件,增加log4j依赖和druid依赖
<!--log4j-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<!--druid-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.5</version>
</dependency>

使用

  1. application.yml配置Druid数据源
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #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,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  1. 添加DruidDataSource 组件到容器中,并绑定属性;
    /*
       将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
       绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
       @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
       前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }
  1. 简单测试我们的数据源是否为Druid
package com.example;

import com.alibaba.druid.pool.DruidDataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

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


@SpringBootTest
class Springboot05DataApplicationTests {

    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() throws SQLException {

        //查看数据源的类型
        System.out.println(dataSource.getClass());

        //获得连接
        Connection connection = dataSource.getConnection();

        System.out.println(connection);

        DruidDataSource druidDataSource = (DruidDataSource) dataSource;
        System.out.println("druidDataSource获得的最大连接数为:"+druidDataSource.getMaxActive());
        System.out.println("druidDataSource初始的连接数为:"+druidDataSource.getInitialSize());

        //关闭连接
        connection.close();
    }

}

image.png

Druid特别的功能

后台监控功能

 //druid后台监控
    //内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
    @Bean//配置 Druid 监控管理后台的Servlet;相当于 web.xml文件
    public ServletRegistrationBean statViewServlet() {
    
        ServletRegistrationBean bean =
                new ServletRegistrationBean(new StatViewServlet(), "/druid/*");


        Map<String, String> initParams = new HashMap<>();
        // 台管理界面的登录账号   固定的,不能变
        initParams.put("loginUsername", "admin");
        ////后台管理界面的登录密码  固定的,不能变
        initParams.put("loginPassword", "123456");

        //后台允许谁可以访问
        //initParams.put("allow", "localhost"):表示只有本机可以访问
        //initParams.put("allow", ""):为空或者为null时,表示允许所有访问
        initParams.put("allow", "");

        //禁止 xiaomi 访问
        //initParams.put("xiaomi","192.168.1.20");

        //初始化参数
        bean.setInitParameters(initParams);

        return bean;
    }

image.png

配置Druid的web监控的filter

    //配置Druid的web监控的filter
    public FilterRegistrationBean webStatFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();

        bean.setFilter(new WebStatFilter());

        //exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
        Map<String, String> initParams = new HashMap<>();
        initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");
        bean.setInitParameters(initParams);

        // "/*" 表示过滤所有请求
        bean.setUrlPatterns(Arrays.asList("/*"));


        return bean;
    }