目录
前言
在软件系统中都会使用到数据库,是开发中大型系统不可缺少的。但如果对数据库资源没有很好地管理,往往会直接导致系统的稳定。随着系统流量、用户的增加,会逐步显露。使用数据库连接池可以更好、更高效的管理数据库连接资源,我们可以直接使用第三方服务,不必自己思索数据库连接的管理。
数据库连接池技术有:DBCP 、tomcat-jdbc、C3P0、HikariCP、Druid
等。
优先推荐 Druid
。它作为国货,更加符合国人的思维,功能丰富,还经历了千锤百炼。
一、数据库连接池
数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
数据库连接池优点:
- 资源重用
- 更快的系统响应速度
- 高效资源分配手段
- 统一的连接管理,避免数据库连接泄漏
二、SpringBoot数据库连接池
SpringBoot 2.2.6 文档说明:
- 由于
HikariCP
的性能和并发性。如果有HikariCP
,SpringBoot 会选择它。 - 否则,如果
Tomcat数据源连接池
可用,也可以使用它。 - 如果
HikariCP
和Tomcat数据源连接池
都不可用,并且如果Commons DBCP2
可用,就使用它。
可以使用 spring.datasource.type
属性来指定要使用的连接池。
如果使用 spring-boot-starter-jdbc
或 spring-boot-starter-data-jpa
,将自动获得对 HikariCP
的依赖。
三、Druid数据库连接池
Druid
连接池是阿里巴巴开源的数据库连接池项目(阿里巴巴数据库事业部出品)。Druid
连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入
,内置Loging
能诊断Hack
应用行为。
Druid
是一个JDBC
组件库,包含数据库连接池、SQL Parser
等组件, 被大量业务和技术产品使用或集成,经历过最严苛线上业务场景考验。是 Java 语言中最好的数据库连接池。
官方提供对比:Druid
连接池在性能、监控、诊断、安全、扩展性这些方面远远超出竞品。
功能类别 | 功能 | Druid | HikariCP | DBCP | Tomcat-jdbc | C3P0 |
---|---|---|---|---|---|---|
性能 | PSCache | 是 | 否 | 是 | 是 | 是 |
LRU | 是 | 否 | 是 | 是 | 是 | |
SLB负载均衡支持 | 是 | 否 | 否 | 否 | 否 | |
稳定性 | ExceptionSorter | 是 | 否 | 否 | 否 | 否 |
扩展 | 扩展 | Filter | JdbcIntercepter | |||
监控 | 监控方式 | jmx/log/http | jmx/metrics | jmx | jmx | jmx |
支持SQL级监控 | 是 | 否 | 否 | 否 | 否 | |
Spring/Web关联监控 | 是 | 否 | 否 | 否 | 否 | |
诊断支持 | LogFilter | 否 | 否 | 否 | 否 | |
连接泄露诊断 | logAbandoned | 否 | 否 | 否 | 否 | |
安全 | SQL防注入 | 是 | 无 | 无 | 无 | 无 |
支持配置加密 | 是 | 否 | 否 | 否 | 否 |
四、SpringBoot集成Druid
1.环境说明
开发工具:IDEA 2019.3.1
框架版本:SpringBoot 2.2.6
数据库:MySql 8.0.19
数据库连接池:Druid 1.1.9
2.集成步骤
(1)添加maven依赖
<!-- Druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
(2)Druid配置
application.properties文件
# ======================================== Druid 配置 ========================================= #
# 要使用的连接池实现的全限定名。默认情况下,它是从类路径自动检测到的。
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# JDBC配置:
# JDBC驱动程序的完全限定名。默认情况下基于URL自动检测
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库的JDBC URL
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
# 数据库登录用户名
spring.datasource.druid.username=root
# 数据库登录密码
spring.datasource.druid.password=root
# 连接池配置:
# 初始化时建立物理连接的个数
spring.datasource.druid.initial-size=2
# 最大连接池数量
spring.datasource.druid.max-active=10
# 最小连接池数量
spring.datasource.druid.min-idle=2
# 属性类型是字符串,通过别名的方式配置扩展插件,配置多个英文逗号分隔。
# 常用的插件有:监控统计用的filter:stat,日志用的filter:log4j,防御sql注入的filter:wall
spring.datasource.druid.filters=stat,wall
# 监控配置:
# WebStatFilter配置
# 是否启用StatFilter默认值false
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
# 排除不必要的url
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
# 是否开启session统计功能
spring.datasource.druid.web-stat-filter.session-stat-enable=true
# session最大数,缺省sessionStatMaxCount是1000个
spring.datasource.druid.web-stat-filter.session-stat-max-count=500
# 用户user信息保存在session中的sessionName,druid能够知道当前的session用户
spring.datasource.druid.web-stat-filter.principal-session-name=web_user
# 用户user信息保存在cookie 中的cookieName,druid能够知道当前的用户
#spring.datasource.druid.web-stat-filter.principal-cookie-name=
# 监控单个url调用的sql列表
spring.datasource.druid.web-stat-filter.profile-enable=true
# StatViewServlet配置
# 是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
spring.datasource.druid.stat-view-servlet.enabled=true
# 访问url模式
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
# 是否允许清空统计数据
spring.datasource.druid.stat-view-servlet.reset-enable=true
# 监控页面访问用户名
spring.datasource.druid.stat-view-servlet.login-username=admin
# 监控页面访问密码
spring.datasource.druid.stat-view-servlet.login-password=admin
# -访问控制:
# -deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝。
# -如果allow没有配置或者为空,则允许所有访问)
# -由于匹配规则不支持IPV6,配置了allow或者deny之后,会导致IPV6无法访问
# 访问控制,白名单IP
#spring.datasource.druid.stat-view-servlet.allow=
# 访问控制,黑名单IP
#spring.datasource.druid.stat-view-servlet.deny=
# Spring监控配置
# Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
#spring.datasource.druid.aop-patterns=
# ======================================== Druid 配置 结束 ========================================= #
DruidDataSource 配置属性列表
DruidDataSource
配置兼容 DBCP
,但个别配置的语意有所区别。
配置 | 缺省值 | 说明 |
---|---|---|
name | 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。如果没有配置,将会生成一个名字,格式是:"DataSource-" + System.identityHashCode(this). 另外配置此属性至少在1.0.5版本中是不起作用的,强行设置name会出错。 | |
url | 连接数据库的url,不同数据库不一样。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
username | 连接数据库的用户名 | |
password | 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。 | |
driverClassName | 根据url自动识别 | 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName |
initialSize | 0 | 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时 |
maxActive | 8 | 最大连接池数量 |
minIdle | 最小连接池数量 | |
maxWait | 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 | |
poolPreparedStatements | false | 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 |
maxPoolPreparedStatementPerConnectionSize | -1 | 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 |
validationQuery | 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 | |
validationQueryTimeout | 单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法 | |
testOnBorrow | true | 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 |
testOnReturn | false | 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 |
testWhileIdle | false | 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 |
keepAlive | false(1.0.28) | 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。 |
timeBetweenEvictionRunsMillis | 1分钟(1.0.14) | 有两个含义: 1) Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。 2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明 |
minEvictableIdleTimeMillis | 连接保持空闲而不被驱逐的最小时间 | |
connectionInitSqls | 物理连接初始化的时候执行的sql | |
exceptionSorter | 根据dbType自动识别 | 当数据库抛出一些不可恢复的异常时,抛弃连接 |
filters | 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall | |
proxyFilters | 类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系 |
(3)监控页面
Druid
内置提供了一个 StatViewServlet
用于展示 Druid
的统计信息。
这个 StatViewServlet
的用途包括:
- 提供监控信息展示的 html 页面
- 提供监控信息的 JSON API
输入 http://127.0.0.1:8080/demo/druid 进入 Druid 监控登录页面,输入配置中的用户名和密码。
进入到 Druid 监控页面,可以看到非常全面的系统监控数据。
总结
目前只是 SpringBoot 集成了 Druid 连接池,并可以进入监控页面进行查看相关监控数据。后期可以将监控页面嵌入到系统中,或是直接获取监控数据自行展示。