Colin is daily life record

导航

数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。

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

最小连接数

是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。

最大连接数

是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。

最小连接数与最大连接数差距
最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。

连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。

不使用连接池流程
下面以访问MySQL为例,执行一个SQL命令,如果不使用连接池,需要经过哪些流程。

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

1.TCP建立连接的三次握手
2.MySQL认证的三次握手
3.真正的SQL执行
4.MySQL的关闭
5.TCP的四次握手关闭

可以看到,为了执行一条SQL,却多了非常多网络交互。

优点:

实现简单
缺点:

网络IO较多
数据库的负载较高
响应时间较长及QPS较低
应用频繁的创建连接和关闭连接,导致临时对象较多,GC频繁
在关闭连接后,会出现大量TIME_WAIT 的TCP状态(在2个MSL之后关闭)
这个过程中每一次发起SQL查询所经历的TCP建立连接,数据库验证用户身份,数据库用户登出,TCP断开连接消耗的等待时间都是可以避免的,这明显是一种浪费。打个比方,你去网吧去玩游戏,每次去到呢先插网线,然后开机登录游戏,玩了一会儿要去上厕所,你就退出游戏,然后关机拔网线。去完厕所回来就又重新插网线开机登游戏

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

第一次访问的时候,需要建立连接。 但是之后的访问,均会复用之前创建的连接,直接执行SQL语句。

优点:

较少了网络开销
系统的性能会有一个实质的提升
没了麻烦的TIME_WAIT状态
所以每次SQL查询都创建链接,查询完后又关闭连接这个做法本身就很扯蛋。合理的做法就应该是系统启动的时候就创建数据库连接,然后需要使用SQL查询的时候,就从系统拿出数据库连接对象并提交查询,查询完了就把连接对象还给系统。系统在整个程序运行结束的时候再把数据库连接关闭。考虑到一般数据库应用都是Web多用户并发应用,那么只有一个数据库连接对象肯定不够用,所以系统启动的时候就应该多创建几个数据库连接对象供多个线程使用,这一批数据库连接对象集合在一起就被称之为数据库连接池。

数据库连接池的工作原理

连接池的工作原理主要由三部分组成,分别为

连接池的建立
连接池中连接的使用管理
连接池的关闭

第一、连接池的建立。

  一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。

Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。

第二、连接池的管理。

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

当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。

当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。

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

第三、连接池的关闭。

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

连接池需要注意的点
1、并发问题

为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。

这个问题相对比较好解决,因为各个语言自身提供了对并发管理的支持像java,c#等等,使用synchronized(java)lock(C#)关键字即可确保线程是同步的。

2、事务处理

我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-OR-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。

我们知道当2个线程共用一个连接Connection对象,而且各自都有自己的事务要处理时候,对于连接池是一个很头疼的问题,因为即使Connection类提供了相应的事务支持,可是我们仍然不能确定那个数据库操作是对应那个事务的,这是由于我们有2个线程都在进行事务操作而引起的。

为此我们可以使用每一个事务独占一个连接来实现,虽然这种方法有点浪费连接池资源但是可以大大降低事务管理的复杂性。

3、连接池的分配与释放

连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。

对于连接的管理可使用一个List。即把已经创建的连接都放入List中去统一管理。每当用户请求一个连接时,系统检查这个List中有没有可以分配的连接。如果有就把那个最合适的连接分配给他,如果没有就抛出一个异常给用户。

4、连接池的配置与维护

连接池中到底应该放置多少连接,才能使系统的性能最佳?

系统可采取设置最小连接数(minConnection)和最大连接数(maxConnection)等参数来控制连接池中的连接。比方说,最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过软件需求上得到。

如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

转载自:https://www.cnblogs.com/cocoxu1992/p/11031908.html、https://www.zhihu.com/question/349816338/answer/854647922

posted on 2024-07-14 13:33  酷酷的瑞瑞  阅读(4)  评论(0编辑  收藏  举报