logo头像

Always believe youself.

数据库连接池

image

官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。

个人理解:创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。

不使用连接池流程

image

不使用数据库连接池的步骤:

1
2
3
4
5
6
TCP建立连接的三次握手
MySQL认证的三次握手
真正的SQL执行
MySQL的关闭
TCP的四次握手关闭
可以看到,为了执行一条SQL,却多了非常多我们不关心的网络交互。

优点:

1
实现简单

缺点:

1
2
3
4
5
网络IO较多
数据库的负载较高
响应时间较长及QPS较低
应用频繁的创建连接和关闭连接,导致临时对象较多,GC频繁
在关闭连接后,会出现大量TIME_WAIT 的TCP状态(在2个MSL之后关闭)

传统的连接机制与数据库连接池的运行机制区别

传统统链接:

Java应用程序访问数据库的过程是:

  • 装载数据库驱动程序;
  • 通过JDBC建立数据库连接;
  • 访问数据库,执行SQL语句;
  • 断开数据库连接。

使用了数据库连接池的机制:
(1) 程序初始化时创建连接池
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池
(4) 程序退出时,断开所有连接,并释放资源

为何要使用数据库连接池

数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。

数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中, 这些数据库连接的数量是由最小数据库连接数来设定的.无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量.连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中.

数据库连接池的最小连接数和最大连接数的设置要考虑到以下几个因素:

  • 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
  • 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
  • 如果最小连接数与最大连接数相差很大:那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接.不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,他将被放到连接池中等待重复使用或是空间超时后被释放.

连接池主要参数

使用连接池时,要配置一下参数

  • 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
  • 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
  • 最大空闲时间
  • 获取连接超时时间
  • 超时重试连接次数

使用数据库连接池的关键点

  • 并发问题 锁
  • 事务处理 DB连接池必须要确保某一时间内一个 conn 只能分配给一个线程。不同 conn 的事务是相互独立的。
  • 连接池的分配与释
  • 连接池的配置与维护 如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

使用数据库连接池的优势和其工作原理

  • 连接池的优势
    • 减少连接创建时间。
    • 简化的编程模式。
    • 控制资源的使用。
  • 连接池的工作原理

连接池技术的核心思想是连接复用,通过建立一个数据库连接池以及一套连接使用、分配和管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。

1
2
3
4
5
6
7
8
9
10
11
12
连接池的工作原理主要由三部分组成,分别为连接池的建立、连接池中连接的使用管理、连接池的关闭。

第一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。

第二、连接池的管理。连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:

当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。
当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。

该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。

第三、连接池的关闭。当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。

常用连接池

dbcp

c3p0

Druid

hikari数据库连接池

HikariCP现在已经是spring-boot-starter-jdbc中自带的默认连接池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
spring:
datasource:
#url: jdbc:mysql://110.40.181.73:3306/sell?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&rewriteBatchedStatements=true
#username: root
#password: 10086
#driver-class-name: com.mysql.cj.jdbc.Driver
#type: com.zaxxer.hikari.HikariDataSource
## Hikari 连接池配置 ------ 详细配置请访问:https://github.com/brettwooldridge/HikariCP
## 最小空闲连接数量
#hikari:
# 空闲连接的最大数量
#minimum-idle: 5
# 空闲连接存活最大时间,默认600000(10分钟)
#idle-timeout: 180000
# 连接池的最大连接数量,超过最大空闲连接的数量之后,经过上面的idle-timeout后连接数量会恢复到minimum-idle
#maximum-pool-size: 10
#connection 事务自动提交,默认就是true
#auto-commit: true
# 连接池名称
#pool-name: myHikaricp
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟,为了防止连接雪崩,通常设置的比数据库的闲置时间小几秒
#max-lifetime: 1800000
# 连接mysql最大超时时间
#connection-timeout: 30000
#connection-test-query: select 1
# 在test 连接是否可用的时候的最大时间,默认500ms,最少 250ms
#validation-timeout: 500
url: jdbc:mysql://110.40.181.73:3306/sell?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&rewriteBatchedStatements=true
username: root
password: 10086
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 5
idle-timeout: 180000
maximum-pool-size: 10
auto-commit: true
pool-name: myHikaricp
max-lifetime: 180000
connection-timeout: 30000
connection-test-query: select 1
validation-timeout: 500