一文说清楚配置数据源的参数

开发 前端
假如链接池中的链接被数据库关闭了,应用经过链接池getConnection时,均可能获取到这些不可用的链接,且这些链接若是不被其余线程回收的话;它们不会被链接池废除,也不会从新被建立,占用了链接池的名额,项目若是是服务端,数据库连接被关闭,客户端调用服务端就会出现大量的timeout,客户端设置了超时时间,会主动断开,服务端就会出现close_wait。

鉴于在开发环境中,我们都使用过yml配置文件,而且我们在yml配置文件中,都加入过连接数据库的配置,也就是配置我们的连接池,但是对于不同的数据库,连接数据库的 Jar 包也都是不一样的,而且对应的配置也是不一样的,今天阿粉就来说说这个 SpringBoot 项目中的,配置数据库连接的各种参数以及不同的数据库,应该是如何配置的。

MySQL的配置

我们先来看配置,然后我们再看看各项配置是什么意思。

spring:

datasource:

name: test

url: jdbc:mysql://localhost:3306/test

username: root

password: xxx

# 使用druid数据源

type: com.alibaba.druid.pool.DruidDataSource

driver-class-name: com.mysql.jdbc.Driver

filters: stat

maxActive: 20

initialSize: 1

maxWait: 60000

minIdle: 1

timeBetweenEvictionRunsMillis: 60000

minEvictableIdleTimeMillis: 300000

validationQuery: select 'x'

testWhileIdle: true

testOnBorrow: false

testOnReturn: false

poolPreparedStatements: true

上面最简单的 name,url,username,password,type 这些阿粉也就不多说了,阿粉需要说的是剩下的参数都是代表的什么含义。

filters

这里配置的是插件,常用的插件有:

监控统计: filter:stat

日志监控: filter:log4j 或者 slf4j

防御SQL注入: filter:wall

maxActive

连接池中最多支持多少个活动会话

initialSize

启动程序时,在连接池中初始化多少个连接

maxWait

程序向连接池中请求连接时,超过maxWait的值后,认为本次请求失败,即连接池没有可用连接,单位毫秒,设置-1时表示无限等待

minIdle

回收空闲连接时,将保证至少有minIdle个连接.

timeBetweenEvictionRunsMillis

检查空闲连接的频率,单位毫秒, 非正整数时表示不进行检查

minEvictableIdleTimeMillis

池中某个连接的空闲时长达到 N 毫秒后, 连接池在下次检查空闲连接时,将回收该连接,要小于防火墙超时设置net.netfilter.nf_conntrack_tcp_timeout_established的设置

validationQuery

检查池中的连接是否仍可用的 SQL 语句,drui会连接到数据库执行该SQL, 如果正常返回,则表示连接可用,否则表示连接不可用

testWhileIdle

当程序请求连接,连接池在分配连接时,是否先检查该连接是否有效。(高效)

testOnBorrow

程序申请连接时,进行连接有效性检查(低效,影响性能)

一般的话,设置均为false

testOnReturn

程序返还连接时,进行连接有效性检查(低效,影响性能)

一般的话,设置均为false

poolPreparedStatements

缓存通过以下两个方法发起的SQL:

public PreparedStatement prepareStatement(String sql)

public PreparedStatement prepareStatement(String sql,int resultSetType, int resultSetConcurrency)

推荐设置为true

其实有些配置,我们是非常熟悉的,为什么这么说,因为经常会有那种连接被关闭的错误,而这个错误则是有可能是参数配置不合适导致的。

配置可能引发的一些问题

其实我们比较需要注意的就是 validationQuery​这个参数,validationQuery是用来验证数据库连接的查询语句,这个查询语句必须是至少返回一条数据的SELECT语句。每种数据库都有各自的验证语句,阿粉也收集了几种常见数据库的validationQuery。

  • hsqldb select 1 from INFORMATION_SCHEMA.SYSTEM_USERS
  • Oracle select 1 from dual
  • DB2 select 1 from sysibm.sysdummy1
  • MySql select 1
  • Microsoft SqlServer select1
  • postgresql select version()
  • ingres select 1
  • derby values 1
  • H2 select 1

而这个参数,一般是否执行,都是靠着 testOnBorrow​ 还有 testOnReturn

testOnBorrow设置为true后如果要生效,validationQuery参数必须设置为非空字符串。

同样的 testOnReturn 设置为true后如果要生效,validationQuery参数必须设置为非空字符串。

但是如果我们设置 testOnBorrow 为 false 的时候,也会出现一些些的问题,

假如链接池中的链接被数据库关闭了,应用经过链接池getConnection时,均可能获取到这些不可用的链接,且这些链接若是不被其余线程回收的话;它们不会被链接池废除,也不会从新被建立,占用了链接池的名额,项目若是是服务端,数据库连接被关闭,客户端调用服务端就会出现大量的timeout,客户端设置了超时时间,会主动断开,服务端就会出现close_wait。

这也是为什么有时候在排查日志的时候,会出现一些 close_wait 的错误,虽然知道并不影响业务,但是日志上看着还是难受。

那么为什么还要设置成 false 呢?

因为 testOnBorrow​ 能够确保我们每次都能获取到可用的连接,但如果设置成 true ,则每次获取连接的时候都要到数据库验证连接有效性,这在高并发的时候会造成性能下降,可以将testOnBorrow设成false,testWhileIdle设置成true这样能获得比较好的性能。

这样也会执行我们上面所说的 validationQuery 参数中的 SQL 来验证连接的有效性。

这样在每次连接失效之后,都会通过validationQuery 来进行验证是否失效。

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2021-07-31 23:14:26

OpenCL框架语言

2021-12-15 09:32:41

Linux系统负载

2023-03-28 07:51:56

CPU主板平台

2020-05-11 07:57:33

区块链分布式链上

2020-04-15 16:34:48

大数据质量标准

2024-09-23 05:10:00

微服务CORSSpringBoot

2020-03-02 15:17:37

云原生CNCF容器

2021-02-11 08:08:09

Spring Boot配置架构

2019-07-04 09:13:04

中台百度团队

2021-02-25 08:21:38

高可用风险故障

2022-07-21 21:19:48

元宇宙

2018-11-28 11:08:30

并查集集合数据结构

2020-10-29 10:35:53

Nginx架构服务器

2019-12-06 09:16:23

Linux 开源操作系统

2021-01-27 08:12:04

Dotnet函数数据

2022-11-11 15:49:41

MySQL隔离

2021-09-15 06:55:34

异步LinqC#

2019-10-21 08:51:41

分布式事务CAPAP

2018-07-26 09:06:29

Java内存模型

2019-02-21 16:24:28

5G火车站设备
点赞
收藏

51CTO技术栈公众号