一、Druid的介绍

Java程序中很多时候都是需要操作数据库,为了提高操作数据库的性能,我们需要使用数据库连接池。Druid是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP等DB池的优点,同时加入了日志监控。

Druid可以很好的监控DB池连接和SQL的执行情况,天生就是针对监控而生的 DB 连接池。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

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

其官网地址为:

https://github.com/alibaba/druid/wiki

二、SpringBoot与Druid整合的依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

 Spring Boot的版本为2.4.2:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

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

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid-spring-boot-starter</artifactId>
	<version>1.2.12</version>
</dependency>

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

切换数据源:之前已经说过 Spring Boot 2.0 以上默认使用 com.zaxxer.hikari.HikariDataSource 数据源,但可以通过 spring.datasource.type 指定数据源。

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: admin
      password: 123456
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;

@SpringBootTest
class DruidDemoApplicationTests {

	@Autowired
	private DataSource dataSource;

	@Test
	void contextLoads() {
		System.out.println(dataSource);
	}
}

数据源切换之后,在测试类中注入 DataSource,然后获取到它,输出一看便知是否成功切换;

三、yml文件中Durid相关配置参数

spring:
  # 数据源
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: admin
      password: 123456
      initialSize: 5
      maxActive: 20
      #获取连接时最大等待时间,单位毫秒
      maxWait: 6000
      #最小连接池数量
      minIdle: 1
      #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      #连接保持空闲而不被驱逐的最小时间,单位是毫秒
      minEvictableIdleTimeMillis: 600000
      maxEvictableIdleTimeMillis: 900000
      #用来检测连接是否有效的sql
      validationQuery: select 1
      #申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
      testWhileIdle: true
      #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      testOnBorrow: false
      #归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      testOnReturn: false
      #asyncInit是1.1.4中新增加的配置,如果有initialSize数量较多时,打开会加快应用启动时间
      asyncInit: true
      stat-view-servlet:
        # enabled值为true时表示开启web监控可视化,值为false时表示关闭web监控可视化
        enabled: true
        # allow选项表示设置“IP访问白名单”(没有配置或者为空,则允许所有访问),其值可以为"119.123.33.172,119.123.33.173",默认本地IP可以访问
        allow: ""
        # url-pattern选项表示配置druid相关访问路径的前缀地址,如果和系统的有冲突,才进行修改,一般不更改
        url-pattern: /druid/*
        # 如果配置了login-username和login-password,则在访问http://localhost:8888/druid/index.html进入到Druid Web管理界面之前需要输入账号和密码
        #login-username: admin
        #login-password: 7654321
      filter:
        stat:
          enabled: true # 是否开启SQL监控
          log-slow-sql: true # 是否开启慢SQL记录日志功能
          slow-sql-millis: 2000 # 默认3000毫秒,这里超过2s,就是慢,记录到日志
          merge-sql: true # 进行SQL统计时是否进行SQL合并
        wall:
          config:
            multi-statement-allow: true # 是否支持批量操作

3.1、Spring.datasource.druid数据库连接配置部分 

1、driver-class-name

这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName

2、initialSize

初始化时建立物理连接的个数,初始化发生在显示调用init方法,或者第一次getConnection时,缺省时其值为0。

3、maxActive

最大连接池数量,缺省时其值为8。

4、maxWaitActive

获取连接时最大等待时间,单位毫秒。

3.2、Spring.datasource.druid.stat-view-servlet部分

1、enabled

enabled值为true时表示开启web监控可视化,值为false时表示关闭web监控可视化

其Web界面的访问地址默认为:http://ip:端口号/druid/index.html

2、allow

allow选项表示设置“IP访问白名单”(没有配置或者为空,则允许所有访问),其值可以为"119.123.33.172,119.123.33.173",默认本地IP可以访问 

3、url-pattern

url-pattern选项表示配置druid相关访问路径的前缀地址,如果和系统的有冲突,才进行修改,一般不更改

4、login-username 和 login-password

如果配置了login-username和login-password,则在访问http://localhost:8888/druid/index.html进入到Druid Web管理界面之前需要输入账号和密码 

3.3、Spring.datasource.druid.filter部分

1、stat.enabled

只有配置spring.datasource.druid.filter.stat.enabled=true时,才能看到SQL监控页面的sql执行情况

如果配置为false,则SQL监控页面会显示空白。

2、stat.log-slow-sql

如果配置spring.datasource.druid.filter.stat.log-slow-sql=true时,则系统日志中会打印慢SQL,为false时则不会打印慢SQL。

PS:另外在logback.xml文件中配置一下相关的日志打印(还没亲自测试过):

<!--druid start-->
<appender name="DruidFile"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <File>${LOG_HOME:-d:/}logs/slow_sql/slow_sql.log</File>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>${LOG_HOME:-d:/}logs/slow_sql/slow_sql-%d{yyyy-MM-dd}.%i.log
        </FileNamePattern>
        <MaxHistory>60</MaxHistory>
        <TimeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <MaxFileSize>5MB</MaxFileSize>
        </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
        </pattern>
    </layout>
    <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>

<logger name="com.alibaba.druid.filter.stat.StatFilter" additivity="false">
    <!-- 这里可以按需配置日志级别 -->
    <level value="error" />
    <appender-ref ref="DruidFile" />
</logger>
<!--druid end-->

根据logback.xml配置,会生产慢sql日志slow_sql.log:

[ERROR] 2022-08-30 22:44:15.651 [http-nio-8080-exec-1] c.a.druid.filter.stat.StatFilter - slow sql 4698 millis. SELECT  id,name,no,create_time,update_time  FROM user[]
[ERROR] 2022-08-30 22:57:15.183 [http-nio-8080-exec-2] c.a.druid.filter.stat.StatFilter - slow sql 3645 millis. SELECT  id,name,no,create_time,update_time  FROM user[]

3、stat.slow-sql-millis

配置spring.datasource.druid.filter.stat.slow-sql-millis表示设置慢查询SQL的阈值,单位是毫秒

4、stat.merge-sql

配置spring.datasource.druid.filter.stat.merge-sql表示是否进行SQL统计时是否进行SQL合并,当前还不知道具体的效果,以后遇到了再回头看看。

5、wall.config.multi-statement-allow

Mybatis集成Druid批量更新时经常会出现下述异常:

Error updating database. Cause: java.sql.SQLException: sql injection violation, multi-statement not allow

导致该异常出现是因为Druid的multiStatementAllow默认是false,所以需要开启,设置成true。 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐