Spring Boot2.0系列教程之整合阿里巴巴数据源druid(七)

什么是druid?

Druid是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和SQL解析器组成。该项目主要是为了扩展JDBC的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计SQL信息、SQL性能收集、SQL注入检查、SQL翻译等,程序员可以通过定制来实现自己需要的功能。 

Druid支持哪些数据库?

Druid支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。 

Druid针对Oracle和MySql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。

为什么说Druid是“最好的数据库连接池”?体现在哪些方面?这是如何实现的?

阿里巴巴是一个重度使用关系数据库的公司,我们在生产环境中大量的使用Druid,通过长期在极高负载的生产环境中实际使用、修改和完善,让Druid逐步发展成最好的数据库连接池。Druid在监控、可扩展性、稳定性和性能方面都有明显的优势。 

 

首先,强大的监控特性,通过Druid提供的监控功能,可以清楚知道连接池和SQL的工作情况。 

  • 监控SQL的执行时间、ResultSet持有时间、返回行数、更新行数、错误次数、错误堆栈信息。
  • SQL执行的耗时区间分布。什么是耗时区间分布呢?比如说,某个SQL执行了1000次,其中0~1毫秒区间50次,1~10毫秒800次,10~100毫秒100次,100~1000毫秒30次,1~10秒15次,10秒以上5次。通过耗时区间分布,能够非常清楚知道SQL的执行耗时情况。
  • 监控连接池的物理连接创建和销毁次数、逻辑连接的申请和关闭次数、非空等待次数、PSCache命中率等。

其次,方便扩展。Druid提供了Filter-Chain模式的扩展API,可以自己编写Filter拦截JDBC中的任何方法,可以在上面做任何事情,比如说性能监控、SQL审计、用户名密码加密、日志等等。 

Druid内置提供了用于监控的StatFilter、日志输出的Log系列Filter、防御SQL注入攻击的WallFilter。 

阿里巴巴内部实现了用于数据库密码加密的CirceFilter,以及和Web、Spring关联监控的DragoonStatFilter。

第三,Druid集合了开源和商业数据库连接池的优秀特性,并结合阿里巴巴大规模苛刻生产环境的使用经验进行优化。

注:第一部分为代码,第二部分为演示Druid数据源操作的截图,完整代码可在github下载。

github地址:https://github.com/zjh746140129/Spring-Boot2.0

项目结构截图:

Spring Boot2.0系列教程之整合阿里巴巴数据源druid(七)_第1张图片

 

一、代码片段

1、编写用户类

package com.boot.entity;


import javax.persistence.*;

/**
 * Created by zhoujh on 2018/7/20.
 */
@Entity
@Table(name = "t_user")
public class User {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(length = 50)
    private String name;

    @Column(length = 50)
    private String word;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getWord() {
        return word;
    }

    public void setWord(String word) {
        this.word = word;
    }
}

2、编写接口

package com.boot.repository;

import com.boot.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Created by zhoujh on 2018/7/20.
 */
public interface UserDao extends JpaRepository {
}

3、编写controller

package com.boot.controller;


import com.boot.entity.User;
import com.boot.repository.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * Created by zhoujh on 2018/7/20.
 */

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserDao userDao;

    @GetMapping(value = "/all")
    public List findAllUser() {
        return userDao.findAll();
    }

    @GetMapping("/find/{id}")
    public User findOneUser(Integer id) {
        return userDao.getOne(id);
    }

    @DeleteMapping("/delete/{id}")
    public void deleteUser(Integer id) {
        userDao.deleteById(id);
    }

    @PostMapping("/add")
    public void addStudentRestful(User user) {
        userDao.save(user);
    }

    @PutMapping("/update")
    public void updateUser(User user) {
        userDao.save(user);
    }
}

4、编写durid的config、filter

package com.boot.config;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

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 com.alibaba.druid.pool.DruidDataSource; //这个包容易导入错误
import com.alibaba.druid.support.http.StatViewServlet; //这个包容易导入错误
import com.alibaba.druid.support.http.WebStatFilter; //这个包容易导入错误

/**
 * Created by zhoujh on 2018/7/20.
 */
@Configuration
public class DruidConfig {

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid() {
        return new DruidDataSource();
    }

    // 配置Druid的监控
    // 1、配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");

        Map initParams = new HashMap<>();
        // 监控页面登录用户名

        initParams.put("loginUsername", "admin");

        // 监控页面登录用户密码
        initParams.put("loginPassword", "123456");

        // ip白名单(没有配置或者为空,则允许所有访问)
        initParams.put("allow", "");

        // ip黑名单(如果某个ip同时存在,deny优先于allow)
        initParams.put("deny", "");
        bean.setInitParameters(initParams);
        return bean;
    }

    // 2、配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        Map initParams = new HashMap<>();

        // 不拦截的静态资源
        initParams.put("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*");
        bean.setInitParameters(initParams);

        // 拦截所有的请求
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }


}
package com.boot.config;

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

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

/**
 * Created by zhoujh on 2018/7/20.
 */
@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*", initParams = {
        @WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略资源
})
public class DruidStatFilter extends WebStatFilter {
}
package com.boot.config;

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

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

/**
 * Created by zhoujh on 2018/7/20.
 */

@SuppressWarnings("serial")
@WebServlet(urlPatterns = "/druid/*", initParams = {
        // IP白名单
        // (没有配置或者为空,则允许所有访问)
        @WebInitParam(name = "allow", value = ""),
        // IP黑名单 (存在共同时,deny优先于allow)
        @WebInitParam(name = "deny", value = ""),
        // 用户名
        @WebInitParam(name = "loginUsername", value = "admin"),
        // 密码
        @WebInitParam(name = "loginPassword", value = "123456"),
        // 禁用HTML页面上的“Reset All”功能
        @WebInitParam(name = "resetEnable", value = "false")
})
public class DruidStatViewServlet extends StatViewServlet {
    private static final long serialVersionUID = 1L;
}

5、启动类

package com.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BooDruidApplication {

	public static void main(String[] args) {
		SpringApplication.run(BooDruidApplication.class, args);
	}
}

6、配置文件

spring.datasource.url=jdbc:mysql://localhost:3306/school_score
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
server.port=8099

# 初始化大小,最小,最大
spring.datasource.initialSize=5  
spring.datasource.minIdle=5  
spring.datasource.maxActive=20  
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000  
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000  
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000  
# 校验SQL,Oracle配置 spring.datasource.validationQuery=SELECT 1 FROM DUAL,如果不配validationQuery项,则下面三项配置无用
spring.datasource.validationQuery=SELECT 'x'  
spring.datasource.testWhileIdle=true  
spring.datasource.testOnBorrow=false  
spring.datasource.testOnReturn=false  
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true  
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20  
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall
#spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;
druid.stat.slowSqlMillis=5000  
# 合并多个DruidDataSource的监控数据
spring.datasource.useGlobalDataSourceStat=true  

7、完整pom.xml



	4.0.0

	com.boot
	boo-druid
	0.0.1-SNAPSHOT
	jar

	boo-druid
	Demo project for Spring Boot

	
		org.springframework.boot
		spring-boot-starter-parent
		2.0.3.RELEASE
		 
	

	
		UTF-8
		UTF-8
		1.8
	

	
		
			org.springframework.boot
			spring-boot-starter-data-jpa
		
		
			org.springframework.boot
			spring-boot-starter-web
		

		
			org.springframework.boot
			spring-boot-devtools
			runtime
		
		
			mysql
			mysql-connector-java
			runtime
		

		
		
			com.alibaba
			druid-spring-boot-starter
			1.1.9
		
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	



 

二、演示druid

1、查询所有,访问 http://localhost:8099/user/all

Spring Boot2.0系列教程之整合阿里巴巴数据源druid(七)_第2张图片

 

 

2、查看druid监控,http://localhost:8099/druid/login.html ,用户名是在config配置的admin和123456

Spring Boot2.0系列教程之整合阿里巴巴数据源druid(七)_第3张图片

 

Spring Boot2.0系列教程之整合阿里巴巴数据源druid(七)_第4张图片

好了,到这里 Spring Boot2.0系列教程之整合阿里巴巴数据源druid就完成了,读者在实践过程中有问题,评论私信即可,回第一时间回复。

你可能感兴趣的:(Spring,Boot,Spring,Boot2.0系列教程)