1. Druid 是什么?
我们先来看一下官方的回答:
Druid 是 Java 语言中最好的数据库连接池。 Druid 能够提供强大的监控和扩展功能。
说 Druid 是 Java 语言中最好的数据库连接池,这个笔者个人觉得有些吹牛了,至少在性能上和我们上一篇介绍的 Hikari 是没得比的,相关的性能测试在网上能找到很多,笔者这边就不列举了。但是 Druid 在其他的一些方面就做的比较出色了,功能非常丰富:
- 可以监控数据库访问性能, Druid 内置提供了一个功能强大的StatFilter插件,能够详细统计 SQL 的执行性能,这对于线上分析数据库访问性能有帮助。
- 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。 DruidDruiver 和 DruidDataSource 都支持 PasswordCallback 。
- SQL 执行日志, Druid 提供了不同的 LogFilter ,能够支持 Common-Logging 、 Log4j 和 JdkLog ,你可以按需要选择相应的 LogFilter ,监控你应用的数据库访问情况。
- 扩展 JDBC ,如果你要对 JDBC 层有编程的需求,可以通过 Druid 提供的 Filter 机制,很方便编写 JDBC 层的扩展插件。
2. Spring Boot 应用中如何使用
目前 Druid 官方为我们提供了两种使用依赖方式,一种是基于传统 Java 工程提供的依赖包, maven 坐标如下:
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.1.20</version>
- </dependency>
还有一种是基于 Spring Boot 提供的依赖包, maven 坐标如下:
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>1.1.20</version>
- </dependency>
下面的这种依赖包除了包含了上面的那种 Druid 基础包,还包含了 Spring Boot 自动配置的依赖包以及 sl4j-api ,我们在 Spring Boot 中使用 Druid ,当然是推荐各位读者使用第二种方式引入依赖。
3. 工程实战
3.1 创建父工程 spring-boot-jpa-druid
父工程 pom.xml 如下:
代码清单:spring-boot-jpa-druid/pom.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.8.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <groupId>com.springcloud</groupId>
- <artifactId>spring-boot-jpa-druid</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>spring-boot-jpa-druid</name>
- <description>spring-boot-jpa-druid</description>
- <properties>
- <druid.version>1.1.20</druid.version>
- <java.version>1.8</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jpa</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <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>${druid.version}</version>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
- 笔者这里使用的 Druid 依赖包是
druid-spring-boot-starter
,版本号为 1.1.20。
3.2 数据库密码不加密的配置文件 application-pass.yml 如下:
代码清单:spring-boot-jpa-druid/src/main/resources/application-pass.yml
- spring:
- datasource:
- type: com.alibaba.druid.pool.DruidDataSource
- url: jdbc:mysql://192.168.0.128:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false
- username: root
- password: 123456
- driverClassName: com.mysql.cj.jdbc.Driver
- druid:
- # 连接池的配置信息
- # 初始化时建立物理连接的个数
- initial-size: 3
- # 连接池最小连接数
- min-idle: 3
- # 连接池最大连接数
- max-active: 20
- # 获取连接时最大等待时间,单位毫秒
- max-wait: 60000
- # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
- test-while-idle: true
- # 既作为检测的间隔时间又作为testWhileIdel执行的依据
- time-between-connect-error-millis: 60000
- # 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接
- min-evictable-idle-time-millis: 30000
- # 用来检测连接是否有效的sql 必须是一个查询语句
- # mysql中为 select 'x'
- # oracle中为 select 1 from dual
- validation-query: select 'x'
- # 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
- test-on-borrow: false
- # 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
- test-on-return: false
- # 是否缓存preparedStatement,mysql5.5+建议开启
- pool-prepared-statements: true
- # 当值大于0时poolPreparedStatements会自动修改为true
- max-pool-prepared-statement-per-connection-size: 20
- # 合并多个DruidDataSource的监控数据
- use-global-data-source-stat: false
- # 配置扩展插件
- filters: stat,wall,slf4j
- # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
- connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
- # 定时输出统计信息到日志中,并每次输出日志会导致清零(reset)连接池相关的计数器。
- time-between-log-stats-millis: 300000
- # 配置DruidStatFilter
- web-stat-filter:
- enabled: true
- url-pattern: '/*'
- exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
- # 配置DruidStatViewServlet
- stat-view-servlet:
- # 是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
- enabled: true
- url-pattern: '/druid/*'
- # IP白名单(没有配置或者为空,则允许所有访问)
- allow: 127.0.0.1,192.168.0.1
- # IP黑名单 (存在共同时,deny优先于allow)
- deny: 192.168.0.128
- # 禁用HTML页面上的“Reset All”功能
- reset-enable: false
- # 登录名
- login-username: admin
- # 登录密码
- login-password: admin
- 相关配置的含义已经写在注释中了,这里有一点要讲一下,当我们要配置统计信息(包括监控信息)
time-between-log-stats-millis
输出至日志中,合并多个DruidDataSource的监控数据use-global-data-source-stat
不可开启,否则启动会报错。 -
spring.datasource.druid.filters
:因为 Druid 的扩展是通过 Filter 插件的形式来开启的,这里我们开启了stat
和wall
,这俩个分别为监控和防御 SQL 注入攻击。 Druid 还提供了一些其他默认的 Filter ,如下表:
Filter类名 别名
default | com.alibaba.druid.filter.stat.StatFilter |
stat | com.alibaba.druid.filter.stat.StatFilter |
mergeStat | com.alibaba.druid.filter.stat.MergeStatFilter |
encoding | com.alibaba.druid.filter.encoding.EncodingConvertFilter |
log4j | com.alibaba.druid.filter.logging.Log4jFilter |
log4j2 | com.alibaba.druid.filter.logging.Log4j2Filter |
slf4j | com.alibaba.druid.filter.logging.Slf4jLogFilter |
commonlogging | com.alibaba.druid.filter.logging.CommonsLogFilter |
wall | com.alibaba.druid.wall.WallFilter |
从名称上可以看出来,主要是一些编码和日志的相关 Filter 。
3.3 数据库密码加密
在生产环境中,直接在配置文件中暴露明文密码是一件非常危险的事情,出于两点考虑:对外,即使应用服务被入侵,数据库还是安全的;对内,生产环境的数据库密码理论上应该只有 dba 知道,但是代码都是在代码仓库中放着的,如果密码没有加密,每次发布前 dba 都需要手动修改配置文件后再进行打包编译。
首先,我们需要生成数据库密码的密文,需要在命令行中执行如下命令:
- java -cp druid-1.0.16.jar com.alibaba.druid.filter.config.ConfigTools you_password
输出如下:
- privateKey:MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAh12hnaZuMe76Yb4pi7ogSAEMOcavmz7Blo8DYxeipxeZQhnrXngxc0gAQ6ORlofLWtDm6S7bI7wfDT2EFy/2DwIDAQABAkABMRjYK3vy4pi/vY3eFhBssd2qsI4hPsczjSTJfY7IC9Dc1f7g0axTM6Cx68tRUwv0rSnUiJ5EcDEhuD0JusSZAiEAwX1HpCTq8QgBV1WriHQC7Cd/9Qqp1V4yJeA/jdvXhbsCIQCzGS6wdTQCXDZKLvjRLeSUyTmmIqV/wckqdnpMUZ2BvQIgBIamr1tBt6OlTGKvoYB9NQLzhkrakCgk6ifltK7IytMCIBIbf67zipiafhqt+RYdD7lDRwLXCeiKzS3v4JmKvuP5AiEAr+zqD6sdXv7rWjqu50n+LXbWtNP/M4JzzO1mJOHEhoE=
- publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIddoZ2mbjHu+mG+KYu6IEgBDDnGr5s+wZaPA2MXoqcXmUIZ6154MXNIAEOjkZaHy1rQ5uku2yO8Hw09hBcv9g8CAwEAAQ==
- password:Y464AerH8tabxQg5DlkUej6gQ64KY73ahgiPyaB0vguLBLjUEEkVu6VBueiXxcnMfVjh1Nbd+lJNUTnS1a3/xg==
这里我们需要将生成的公钥 publicKey
和密码 password
加入配置文件中, application-decrypt.yml
如下:
代码清单:spring-boot-jpa-druid/src/main/resources/application-decrypt.yml
- spring:
- datasource:
- type: com.alibaba.druid.pool.DruidDataSource
- url: jdbc:mysql://192.168.0.128:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false
- username: root
- # 加密后密文,原密码为 123456
- password: Y464AerH8tabxQg5DlkUej6gQ64KY73ahgiPyaB0vguLBLjUEEkVu6VBueiXxcnMfVjh1Nbd+lJNUTnS1a3/xg==
- driverClassName: com.mysql.cj.jdbc.Driver
- druid:
- filter:
- config:
- enabled: true
- connection-properties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIddoZ2mbjHu+mG+KYu6IEgBDDnGr5s+wZaPA2MXoqcXmUIZ6154MXNIAEOjkZaHy1rQ5uku2yO8Hw09hBcv9g8CAwEAAQ==
- # 剩余配置省略
- 已省略部分配置,有需要的读者可以访问 Github 仓库获取。
3.4 配置文件 application.yml
如下:
代码清单:spring-boot-jpa-druid/src/main/resources/application.yml
- server:
- port: 8080
- spring:
- application:
- name: spring-boot-jpa-druid
- profiles:
- active: decrypt
- jpa:
- database: mysql
- show-sql: true
- generate-ddl: true
- database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
- hibernate:
- ddl-auto: update
- properties:
- hibernate:
- format_sql: true
4. 测试
我们在主配置文件中,选择密码加密的配置文件启动,将 spring.profiles.active
配置为 decrypt
,点击启动,可以看到工程正常启动,查看控制台输出日志,其中有这么一句:
- 2019-09-22 21:21:54.501 INFO 16972 --- [-Log-1465691120] c.a.d.p.DruidDataSourceStatLoggerImpl : {"url":"jdbc:mysql://192.168.0.128:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false","dbType":"mysql","name":"DataSource-1465691120","activeCount":0,"poolingCount":3,"poolingPeak":3,"poolingPeakTime":"2019-09-22 21:21:54","connectCount":0,"closeCount":0,"physicalConnectCount":3}
可以看到,我们配置的监控信息输出会在系统启动的时候先输出一次,我们在配置文件中配置的是每5分钟输出一次,等十分钟看一下控制台的输出信息,结果如下:
- 2019-09-22 21:26:54.503 INFO 16972 --- [-Log-1465691120] c.a.d.p.DruidDataSourceStatLoggerImpl : {"url":"jdbc:mysql://192.168.0.128:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false","dbType":"mysql","name":"DataSource-1465691120","activeCount":0,"activePeak":1,"activePeakTime":"2019-09-22 21:21:54","poolingCount":3,"poolingPeak":3,"poolingPeakTime":"2019-09-22 21:21:54","connectCount":2,"closeCount":2,"connectionHoldTimeHistogram":[0,0,2]}
- 2019-09-22 21:31:54.505 INFO 16972 --- [-Log-1465691120] c.a.d.p.DruidDataSourceStatLoggerImpl : {"url":"jdbc:mysql://192.168.0.128:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false","dbType":"mysql","name":"DataSource-1465691120","activeCount":0,"poolingCount":3,"connectCount":0,"closeCount":0}
- 2019-09-22 21:36:54.505 INFO 16972 --- [-Log-1465691120] c.a.d.p.DruidDataSourceStatLoggerImpl : {"url":"jdbc:mysql://192.168.0.128:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false","dbType":"mysql","name":"DataSource-1465691120","activeCount":0,"poolingCount":3,"connectCount":0,"closeCount":0}
从时间上可以看出,确实是每5分钟会输出一次。
打开浏览器访问:http://localhost:8080/druid/ ,查看 Druid 监控页面,结果如图:
我们可以进行一些接口测试,在查看监控页面,可以看到所有的 SQL 都正常记录,如图:
- <a target="_blank" href="https://cdn.geekdigging.com/images/spring-boot/jpa-druid/druid-dashboard-3.png" class="fluidbox fluidbox__instance-6 fluidbox--initialized fluidbox--closed fluidbox--ready" style="background-color: transparent; color: #0088cc;">2019-09-22 21:51:54.506 INFO 16972 --- [-Log-1465691120] c.a.d.p.DruidDataSourceStatLoggerImpl : {"url":"jdbc:mysql://192.168.0.128:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false","dbType":"mysql","name":"DataSource-1465691120","activeCount":0,"activePeak":1,"activePeakTime":"2019-09-22 21:47:28","poolingCount":3,"poolingPeak":3,"poolingPeakTime":"2019-09-22 21:47:28","connectCount":4,"closeCount":4,"executeCount":4,"commitCount":4,"pstmtCacheHitCount":2,"pstmtCacheMissCount":2,"startTransactionCount":4,"transactionHistogram":[0,1,2,1],"connectionHoldTimeHistogram":[0,1,0,3],"sqlList":[{"sql":"insert into user (age, nick_name, id) values (?, ?, ?)","executeCount":2,"executeMillisMax":1,"executeMillisTotal":2,"executeHistogram":[1,1],"executeAndResultHoldHistogram":[1,1],"concurrentMax":1,"updateCount":2,"updateCountMax":1,"updateHistogram":[0,2],"inTransactionCount":2},{"sql":"select usermodel0_.id as id1_0_, usermodel0_.age as age2_0_, usermodel0_.nick_name as nick_nam3_0_ from user usermodel0_ order by usermodel0_.id desc","executeCount":2,"executeMillisMax":3,"executeMillisTotal":4,"executeHistogram":[0,2],"executeAndResultHoldHistogram":[2],"concurrentMax":1,"fetchRowCount":4,"fetchRowCountMax":2,"fetchRowHistogram":[0,2],"inTransactionCount":2}]}</a>
可以看到,日志中打印了我们执行的 SQL 相关的信息,和我们在监控页面看到的信息完全一致。
至此,测试成功,篇幅原因,一些测试过程未列出,各位感兴趣的读者朋友可以自己动手尝试一下。
相关推荐
本文将详细介绍如何在Spring Boot项目中整合Druid连接池,并通过非对称加密技术加密数据库密码,从而提高系统的安全性。 #### 二、项目搭建与环境准备 ##### 2.1 新建 Maven 项目 首先,我们需要使用IDEA...
Spring Boot 配置 Druid 连接池的完整步骤 Spring Boot 是一个基于 Java 的开源框架,用于构建微服务架构的应用程序。 Druid 是一个功能强大且高效的数据库连接池,由阿里巴巴开发,已经在生产环境中广泛应用。 ...
集成 Druid 后,Spring Boot 应用不仅可以使用高性能的数据库连接池,还能享受到其丰富的监控功能,如监控后台、SQL 执行统计、连接池状态查看等,这些都有助于优化数据库操作,提高系统的整体性能和可维护性。...
SpringBoot 整合 Mybatis 使用 Druid 数据库连接池 ...Spring Boot 整合 Mybatis 使用 Druid 数据库连接池,能够提供高效、安全、可靠的数据库连接池管理能力,满足高并发、安全、可靠性的应用程序需求。
Spring Boot下Druid连接池的使用配置分析 Spring Boot是一个基于Java的开源框架,提供了许多简洁、灵活的特性,而Druid是一个由阿里系开源的JDBC组件,提供了高效、功能强大的数据库连接池和监控功能。在本文中,...
Druid是一个强大的、高性能的数据库连接池组件,它不仅提供了基本的连接池功能,还支持监控、SQL解析和拦截器等功能,是许多企业级应用的首选。 首先,让我们深入了解Druid数据源。Druid是一个全面的数据库连接池...
DRUID 是阿里巴巴开源的数据库连接池,提供了数据源监控、SQL 执行分析、Web 应用防火墙等功能,在 Spring Boot 中可以通过依赖的方式引入 DRUID,实现数据源监控和加密。 5. 数据源监控实现过程 数据源监控实现...
- Druid是一个高性能的数据库连接池,提供了监控、SQL解析、连接池等功能。 - 连接池管理:为应用程序提供数据库连接的复用,提高数据库访问效率。 - 监控:内置监控统计,可以通过Web页面查看连接池状态、SQL...
3. 在`application.properties`中配置Druid连接池: ``` spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&...
Druid 是一个功能强大、性能高效的数据库连接池,它提供了多种功能,如监控数据库访问性能、数据库密码加密、SQL 执行日志等。下面将介绍如何在 Spring Boot 项目中配置 Druid 连接池。 Druid 的简介 Druid 是阿里...
- 使用日志或专门的监控工具(如Spring Boot Actuator)收集和分析连接池的运行数据。 6. **事务管理**: - 连接池通常支持事务管理,如自动提交、手动提交、回滚等。 - 注意事务的隔离级别和传播属性对性能和...
Druid是阿里巴巴开源的一个强大数据库连接池组件,它不仅提供了监控、扩展性,还集成了SQL解析、执行计划等功能,是Spring Boot中常用的高性能数据库连接池选择。 3. **Ehcache缓存管理**: Ehcache是Java的一个...
基于SpringBoot + Vue 的电影售票及影院管理系统(前后端分离) 后端:Spring Boot + Mybatis 实现功能: 售票子系统:用户浏览电影信息,电影分类查看,搜索查看,购票...数据库连接池:druid 分页插件:pageHelper
* 数据库连接池:Alibaba Druid * 数据库缓存:Redis Sentinel * 消息中间件:RabbitMQ (后期考虑加入) * 接口文档引擎:Swagger2 RESTful 风格 API 文档生成 * 全文检索引擎:ElasticSearch (后期考虑加入) * ...
配置Druid连接池涉及许多参数,如初始化大小、最大活跃连接数、最小空闲连接数等,同时还可以配置监控统计拦截器。 5. **Spring Boot的多数据源配置**:如果项目需要连接多个数据库,Spring Boot支持多数据源配置,...
在Spring Boot中,通过配置MyBatis的相关属性,如Mapper扫描路径,以及设置MyBatis的SqlSessionFactoryBean的dataSource属性为Druid的数据源,这样MyBatis就会使用Druid连接池。 然后,为了实现分页查询,我们需要...
本文讲解了Spring Boot认证鉴权相关知识点,包括MyBatis-Plus、Druid数据库连接池、统一返回实体ResponseResult、Spring Boot认证鉴权机制、Redis在认证鉴权中的应用、Spring Boot与Shiro集成、Spring Boot与JWT集成...
- `druid-spring-boot-starter`:阿里云提供的高性能 JDBC 数据库连接池。 - `sharding-jdbc-spring-boot-starter`:Sharding-JDBC 的 Spring Boot 版本依赖包。 ##### 2. 配置文件 `application.properties` 接...
数据库连接池:druid 分页插件:pageHelper vue安装对应的版本: nodejs 14.xx npm 6.xx vue 2.x 适用人群:学习不同技术领域的小白或进阶学习者;可作为毕设项目、课程设计、大作业、工程实训或初期项目...
Druid能够提供SQL解析、执行计划展示、连接池诊断、性能分析等功能,是Spring Boot项目中常用的数据库连接池选择。 **Swagger** 是一种用于设计、构建、记录和使用RESTful API的工具。它通过使用OpenAPI ...