数据库连接池
前言:在后端开发过程中,有很多技能是必备的,比如我们今天说到的数据库;后端人员与数据库打交道是最多的;当然,数据库连接并不是我们所想的那么简单,知识单纯的连接一下就OK了,其实在这其中还有很多的坑等着我们去踩,我这里提出来几个点,大家可以思考一下:
1.数据库连接后,怎么防止断开,断开会又是怎么重连的
2.数据库带宽打满后,数据库超时,我们需要怎么处理
3.数据库异常,我们又改怎么处理?
4.数据库连接池连接数越大越好吗?
这些都是我在做项目中遇到的问题,这些问题大家可以留言一起讨论,这边文章就不作回答了。
一、数据库连接池
什么是数据库连接池?其实数据库池就是好比我们有很多的玩具放在一个储物柜中,其中玩具就是我们的数据库连接,储物柜就是我们池子;我们需要玩具时就存储物柜中,使用完后会将玩具放入储物柜;这样,我们就会有源源不断的玩具供我们使用,也就是我们会有源源不断的连接供我们使用。
二、使用连接池的原因
数据库连接是一种关键的有限的昂贵的资源, 一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的 性能低下。 数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并讲这些连接组成一个连接池(简单说:在一个“池”里放了好多半成品的数据库联接对象),由应用程序动态地对池中的连接进行申请、使用和释放。对于多于连接池中连接数的并发请求,应该在请求队列中排队等待。并且应用程序可以根据池中连接的使用率,动态增加或减少池中的连接数。 连接池技术尽可能多地重用了消耗内存地资源,大大节省了内存,提高了服务器地服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况。
三、连接池使用的优点
1.数据库连接过程
执行数据库语句流程
1.TCP建立连接的三次握手
2.MySQL认证的三次握手
3.真正的SQL执行
4.MySQL的关闭
5.TCP的四次握手关闭
缺点:
网络IO较多
数据库的负载较高
响应时间较长及QPS较低
应用频繁的创建连接和关闭连接,导致临时对象较多
在关闭连接后,会出现大量TIME_WAIT 的TCP状态(在2个MSL之后关闭)
2.数据库池连接
使用数据库连接池的步骤:
第一次访问的时候,需要建立连接。 但是之后的访问,均会复用之前创建的连接,直接执行SQL语句。
优点:
较少了网络开销
系统的性能会有一个实质的提升
没了麻烦的TIME_WAIT状态
三、连接池的工作原理
连接池的工作原理主要由三部分组成,分别为
连接池的建立
连接池中连接的使用管理
连接池的关闭
第一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等
第二、连接池的管理。连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:
当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。
当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。
该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。
第三、连接池的关闭。当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。
四、案例
最近在github看到一个数据库连接池,顺便按照这个做一个解析:
这个数据库连接池做的比较简单,但是中间是有比较多的问题的:
1.正常项目中,数据库连接一般会放在配置文件中,避免硬编码
2.数据库连接应该放在初始化中,建立好固定连接数,如果在程序执行过程中执行的话,速度回比较慢。
3.对于连接池的维护,更合适的做法是使用线程定时器去不断检测,并且要做好异常措施。
大家可以根据这个思路进行对代码修改。
github:https://github.com/primer9999/MysqlPool
想了解学习更多C++后台服务器方面的知识,
请关注: 微信公众号:C++后台服务器开发