Spring Boot项目中集成连接池及部分细节说明

连接池

为了节省数据库资源与提升运行效率,一般都会在项目中集成连接池,平时只是引入依赖,写好配置就直接用了,很多细节没有考虑过,这里做一下记录。

一,Connection连接

什么是Connection连接呢?

Connection对象是和数据库建立的通信连接对象,执行SQL的底层逻辑就要通过Connection对象实现。(讲得有点迷,不是太懂)

实际操作一下吧。

我们查到通过如下命令可以查到MySQL当前连接数量:

  • 该命令可以列出当前所有连接到MySQL的客户端,以及每个连接的详细信息,包括ID、用户、主机、数据库、命令、时间等。
powershell 复制代码
mysql> SHOW PROCESSLIST;
  • 该命令将返回Threads_connected状态变量的当前值,该变量记录了已建立的当前连接数。
powershell 复制代码
mysql> SHOW STATUS LIKE 'Threads_connected';

我们进入MySQL服务,执行上述的命令,下面是我本机执行的结果:

上面显示我本机的MySQL目前有两个连接,一个应该是我打开的这个命令行窗口的连接,另一个连接有可能是Navicat打开得,因为之前用Navicat查看过数据库。可以关掉Navicat的连接再试一次。

应该是了,关掉Navicat以后连接只有一个了,这样就容易理解Connection为什么是数据库连接对象了。

二,数据库连接池

上面我们知道了什么是Connection,那数据库连接池又是什么呢?

先来说说线程池Executors ,我们通过Executors.newFixedThreadPool(10);可以创建一个定长的线程池,线程池里最大有10个线程,线程池创建了线程,执行完成任务后该线程不会销毁,而是放在线程池中,等待下一次任务的处理。

通过线程池,由此及彼,那数据库连接池也是预先创建一批数据库连接对象,将它们放入数据库连接池中,当有数据库操作任务时,就从连接池中取出预先创建好的连接对象来执行相应的任务。

三,集成数据库连接池

1,Spring Boot默认连接池

数据库连接池技术有:DBCP、tomcat-jdbc、C3P0、HikariCP、Druid等。

若没有引入额外的连接池,Spring Boot 2.x默认使用HikariCP作为项目的数据库连接池。

可以通过下面的代码测试当前项目的连接池:(Spring Boot版本:2.5.0)

java 复制代码
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.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

@SpringBootTest
public class DataSourceTest {

    @Autowired
    private DataSource dataSource;

    @Test
    public void testDataSource() {
        System.out.println("连接类型:" + dataSource.getClass());
        try {
            // 获得数据库连接
            Connection connection = dataSource.getConnection();
            System.out.println("数据库连接对象:" + connection);
            // 关闭连接
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
powershell 复制代码
连接类型:class com.zaxxer.hikari.HikariDataSource
数据库连接对象:HikariProxyConnection@991572261 wrapping com.mysql.cj.jdbc.ConnectionImpl@4199761d

可以发现Spring Boot默认集成的数据库连接池是HikariCP。HikariCP有着很高的性能和并发性,是SpringBoot默认使用的连接池。

2,Druid连接池

  • Druid是阿里巴巴开源的数据库连接池项目,后来贡献给了Apache开源;
  • Druid的作用是负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个;
  • Druid连接池内置强大的监控功能,其中的StatFilter功能,能采集非常完备的连接池执行信息,方便进行监控,而监控特性不影响性能;
  • Druid连接池内置了一个监控页面,提供了非常完备的监控信息,可以快速诊断系统的瓶颈。

3,集成Druid(原生版本)

Druid依赖有两个,一个是原生的依赖,另一个是再次封装的springboot-starter依赖。

3.1,引入依赖

原生依赖如下:

xml 复制代码
<!--druid-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.4</version>
</dependency>

除Druid外,还需引入下面的依赖

xml 复制代码
<!--各依赖版本需根据SpringBoot确定,当前项目SpringBoot:2.5.0-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.5.0</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <version>2.5.0</version>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
</dependency>

3.2,配置数据源

yaml 复制代码
#设置数据库连接信息
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
    username: root
    password: 12345
    # type指定数据源类型,当前类型Druid
    type: com.alibaba.druid.pool.DruidDataSource

用之前的代码测试数据源可以发现数据源已由HikariCP变为了Druid,数据源指定成功。

java 复制代码
连接类型:class com.alibaba.druid.pool.DruidDataSource
数据库连接对象:com.mysql.cj.jdbc.ConnectionImpl@3c1908c8

3.3,编写配置文件

yaml 复制代码
#设置数据库连接信息
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
    username: root
    password: 12345
    # type可以指定数据源类型
    type: com.alibaba.druid.pool.DruidDataSource
    # druid数据源相关配置
    # 初始化大小
    initialSize: 5
    # 最小连接数
    minIdle: 10
    # 最大连接数
    maxActive: 20
    # 获取连接时的最大等待时间
    maxWait: 60000
    # 一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRuns-millis: 60000
    #验证库是否正常sql
    validationQuery: select 'x'
    #空闲时验证,防止连接断开
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,slf4j
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

3.4,开启Druid数据源监控

Druid数据源具有监控的功能,并提供了一个web界面方便用户查看。以下配置文件中配置了Druid监控后台的Servlet,以及Web和Druid数据源之间的管理关联监控统计。

java 复制代码
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.HashMap;

/**
 * @author zhhao
 * @date 2024-01-30 12:02
 * @describe
 */
@Configuration
public class DruidConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")//和配置文件绑定
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }

    //获取后台监控
    @Bean
    //由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件。
    // 所以想用使用Servlet功能,就必须要借用SpringBoot提供的ServletRegistrationBean接口。
    public ServletRegistrationBean servletRegistration(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");   //StatViewServlet用于展示Druid的统计信息

        //设置后台登录的账户和密码
        HashMap<String, String> initParameters = new HashMap<>();

		// IP白名单
        initParameters.put("allow","");
        // IP黑名单(共同存在时,deny优先于allow)
        initParameters.put("deny","");

        //增加配置 登录的key是固定的
        initParameters.put("loginUsername","admin");
        initParameters.put("loginPassword","123456");

        //设置谁可以访问
        initParameters.put("allow","");//任何人都可以访问

        //设置初始化参数
        bean.setInitParameters(initParameters);

        return bean;
    }

    /**
     * 用于配置Web和Druid数据源之间的管理关联监控统计
     * @return
     */
    @Bean
    public FilterRegistrationBean webStartFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        //可以过滤的请求
        HashMap<String, String> initParameters = new HashMap<>();

        //排除一些不必要的url
        initParameters.put("exclusions","*.js,*.css,/druid/*");

        bean.setInitParameters(initParameters);//设置初始化参数
        return bean;
    }

}

3.5,测试

刚打开页面里面没有数据,当执行了SQL后,会显示执行的SQL,以及当前数据源的配置信息。

  • 测试数据库连接数:
    配置文件中初始化连接数为5,可以启动项目测试一下看连接是否生效。
    项目未启动时数据库连接数:只有一个连接,是我们打开的命令行窗口
  • 项目启动后:

    数据库连接数变为了6个,多出来的一个是CMD窗口连接,说明配置生效。

4,集成Druid(Starter)

4.1,引入依赖

该依赖是封装后的springboot-starter依赖,可以更方便的集成到Spring Boot项目中。

Github:druid-spring-boot-starter

xml 复制代码
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.1</version>
</dependency>

4.2,编写配置文件

yaml 复制代码
#设置数据库连接信息
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/tick_tack?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
    username: root
    password: 12345
    # type可以指定数据源类型
    type: com.alibaba.druid.pool.DruidDataSource
    # druid数据源相关配置
    druid:
      # 初始化大小
      initial-size: 5
      # 最小连接数
      min-idle: 5
      # 最大连接数
      max-active: 20
      # 获取连接时的最大等待时间
      max-wait: 60000
      # 一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 检测连接是否有效的sql语句,为空时以下三个配置均无效
      validation-query: select 1
      # 申请连接时执行validationQuery检测连接是否有效,默认true,开启后会降低性能
      test-on-borrow: true
      # 归还连接时执行validationQuery检测连接是否有效,默认false,开启后会降低性能
      test-on-return: true
      # 申请连接时如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效,默认false,建议开启,不影响性能
      test-while-idle: true
      stat-view-servlet:
        # 是否开启StateViewServlet
        enabled: true
        # 访问监控页面 白名单,默认127.0.0.1
        allow: 127.0.0.1
        # 访问监控页面 黑名单
        deny: 192.168.56.1
        login-username: admin
        login-password: 123456
      filter:
        stat:
          # 是否开启FilterStat,默认为true
          enabled: true
          # 是否开启慢SQL记录,默认false
          log-slow-sql: true
          # 河北多个连接池的监控数据,默认false
          merge-sql: false

引入spring-boot-starter依赖后就不需要再额外编写配置类了,上面的配置文件里可以配置监控信息

4.3,测试

启动项目,监控页面:http://localhost:7080/demo/druid/

查看数据库连接数也可以发现连接数已建立

相关推荐
xmh-sxh-131414 分钟前
jdk各个版本介绍
java
XINGTECODE27 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
天天扭码33 分钟前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶33 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺38 分钟前
Spring Boot框架Starter组件整理
java·spring boot·后端
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue
凡人的AI工具箱1 小时前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
陈王卜1 小时前
django+boostrap实现发布博客权限控制
java·前端·django
小码的头发丝、1 小时前
Spring Boot 注解
java·spring boot
先天牛马圣体1 小时前
如何提升大型AI模型的智能水平
后端