三篇文章:
第一篇——从技术角度阐述为什么使用数据库连接池
第二篇——将传统连接和数据库连接池对比
第三篇——总结连接池的好处,工作原理,存在的问题,常用连接池
文章目录
- java基础
- 一、不使用连接池的劣势
- 二、数据库连接池技术带来的优势
- 三、数据库连接池的工作原理
- 四、连接池需要注意的问题
- 五、常用连接池的比较
- 1、常用的数据库连接池:
- 2、自定义连接池的大致思路:
- 3、Druid 相对于其他数据库连接池的优点
- 六、配置指标(学习考虑的角度)
- 七、数据库连接池面试题
一、不使用连接池的劣势
- 数据库连接是一种关键的有限的昂贵的资源
- 数据库连接体现在网络的TCP/IP 连接
- 应用频繁的创建连接和关闭连接,导致临时对象较多,GC频繁
- 建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源
- 网络IO较多,数据库的负载较高
- 在高并发的情况下,频繁的进行数据库连接 *** 作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃
- 响应时间较长及QPS较低
- 如果有太多的连接要断开,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏
- 要处理大量的连接收尾工作,大量TIME_WAIT 的TCP状态(2MSL之后关闭)
- 不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,连接过多,可能导致内存泄漏, 造成服务器的崩溃
- 频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈
1、资源重用
由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程/线程的数量)。
2、更快的系统响应速度
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销和网络开销,从而缩减了系统整体响应时间。
3、新的资源分配手段
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源。
4、统一的连接管理,避免数据库连接泄漏
在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接。从而避免了常规数据库连接 *** 作中可能出现的资源泄漏。
两者之间的巨大差距就是我们使用连接池的原因
三、数据库连接池的工作原理连接池的工作原理主要由三部分组成,分别为
- 连接池的建立
- 连接池中连接的使用管理
- 连接池的关闭
1、连接池的建立
一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。
Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。
2、连接池的管理
连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:
当客户请求数据库连接时:
1)如果池中有空闲连接可用,返回该连接。
2)如果没有空闲连接,池中连接都已用完,创建一个新连接添加到池中。
3)如果池中连接已达到最大连接数,请求按设定的最大等待时间进入等待队列直到有空闲连接可用。
4)如果超出最大等待时间,则抛出异常给客户。
当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。
该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。
如果连接长时间空闲,或检测到与服务器的连接已断开,连接池管理器也会将该连接从池中移除。
3、连接池的关闭
当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。
1、并发问题
为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为各个语言自身提供了对并发管理的支持像java,c#等等,使用synchronized(java)lock(C#)关键字即可确保线程是同步的。使用方法可以参考,相关文献。
2、事务处理
我们知道,事务具有原子性,此时要求对数据库的 *** 作符合“ALL-OR-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。
我们知道当2个线程共用一个连接Connection对象,而且各自都有自己的事务要处理时候,对于连接池是一个很头疼的问题,因为即使Connection类提供了相应的事务支持,可是我们仍然不能确定那个数据库 *** 作是对应那个事务的,这是由于我们有2个线程都在进行事务 *** 作而引起的。为此我们可以使用每一个事务独占一个连接来实现,虽然这种方法有点浪费连接池资源但是可以大大降低事务管理的复杂性。
3、连接池的分配与释放
连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。
对于连接的管理可使用一个List。即把已经创建的连接都放入List中去统一管理。每当用户请求一个连接时,系统检查这个List中有没有可以分配的连接。如果有就把那个最合适的连接分配给他(如何能找到最合适的连接文章将在关键议题中指出);如果没有就抛出一个异常给用户,List中连接是否可以被分配由一个线程来专门管理捎后我会介绍这个线程的具体实现。
4、连接池的配置与维护
连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minConnection)和最大连接数(maxConnection)等参数来控制连接池中的连接。比方说,最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过软件需求上得到。
如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。
- C3P0:数据库连接池,速度相对较慢,稳定性不错,Hibernate, spring
- Proxool:数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
- HakariCP:性能杀手
- BoneCP :数据库连接池,速度快,很小,只有四十几K,不灵活
- DBCP:数据库连接池,速度相对c3p0较快,但不稳定,Apache,Tomcat
- Druid:德鲁伊,阿里巴巴国货,中文文档,优点集于一身
一些优秀的开源数据库连接池和自定义连接池的使用差不多
- 导入jar包
- 读取配置文件将属性值取出
- 注册JDBC
- 通过数据库连接数和驱动管理器获得相应连接(.getConnection()),因为DataSource是接口,所以这个方法需要我们手动实现。
- 重点:实现getConnection()方法
思考:当外部有连接需求时,直接从connectList拿出一个connect,就实现了这个方法,但是我们再想想,它用完了怎么回收呢,确实,有close()方法,但是这个方法作用是将这个连接还给数据库,而不是数据库连接池,这样会导致数据库连接池中 的连接越来越少,这样可不行,但是我们也不能影响它的正常使用吧,在这种情况下,我们想要监测这个连接对象的动态,在它调用close()方法时,我们将其再添加进connectList,这样连接池中的连接不就没少了吗,在java中对于监听一个对象的动态,最常用也最实用的便是动态代理,对于动态代理,其实我们可以把它想象成就是一个大盒子,里面装着一个真实对象小盒子,这就在大盒子和小盒子间形成了一个横切空隙,而真实做事的还是这个对象,代理只是个接活的,接到活就给内部的小盒子干,自然这个空隙可以用来监测真实对象的事务,也就是监听对象的方法。具体可以看看这个,动态代理:https://www.cnblogs.com/xdp-gacl/p/3971367.html
强大的监控特性,通过Druid提供的监控功能,可以清楚知道连接池和SQL的工作情况。
-
监控SQL的执行时间、ResultSet持有时间、返回行数、更新行数、错误次数、错误堆栈信息;
-
SQL执行的耗时区间分布。什么是耗时区间分布呢?比如说,某个SQL执行了1000次,其中01毫秒区间50次,110毫秒800次,10100毫秒100次,1001000毫秒30次,1~10秒15次,10秒以上5次。通过耗时区间分布,能够非常清楚知道SQL的执行耗时情况;
-
监控连接池的物理连接创建和销毁次数、逻辑连接的申请和关闭次数、非空等待次数、PSCache命中率等。
方便扩展。Druid提供了Filter-Chain模式的扩展API,可以自己编写Filter拦截JDBC中的任何方法,可以在上面做任何事情,比如说性能监控、SQL审计、用户名密码加密、日志等等。
Druid集合了开源和商业数据库连接池的优秀特性,并结合阿里巴巴大规模苛刻环境测试。
比较了多种连接池的优劣,下面这个话题可能和比较本身没有直接关系,但个人认为应该是更有价值的一些经验分享吧,那就是—这么多指标配置,那些最大和最小连接数以及其他一些必要的配置指标,在一个正式的生产项目中到底应该配置什么值呢?
其实这个值首先还是要根据具体的项目情况、数据规模以及并发数来制定的(尽管像是套话,但是我们研发人员严谨的作风还是必要的:)。具体而言在中型偏小型的项目–给个数值把,用户数300到3000,数据量100万到1亿—中,建议weblogic设置为最大和最小都是200,websphere最小200最大300,前提是2者设置的最小内存要在1G以上,当然如果条件允许内存越大越好,不过32位机内存1.5G的限制是一定的(64位嘛我愿意设个4G内存过来,速度提升的感觉很爽啊)。这个数字出来以后相信会有不少问题要抛过来,我一一谈一下自己的体验和想法吧
1 为什么是200或300而不是更高?
回答: 再分配多了效果也不大了,一个是应用服务器维持这个连接数需要内存支持,刚才说了32位的机器只能支持到1.5G,并且维护大量的连接进行分配使用对cpu也是一个不小的负荷,因此不宜太大。
2 为什么不小一点?
回答: 如果太小,那么在上述规模项目的并发量以及数据量上来以后会造成排队现象,系统会变慢,数据库连接会经常打开和关闭,性能上有压力,用户体验也不好。
3 为什么weblogic最小最大都一样,而websphere不一样
回答: 其实和分配内存的最小最大值的情况一样,一般都推荐2个值应该一致,都放在内存里就好了嘛。但是ibm官方推荐2个值要有区别—官方说法还是要听的
4 其他开源连接池的分配方案还没说呢?
回答: 开源的个人认为到100就可以了,再高他也不会太稳定,当然1G的最小内存是一定要给tomcat分的
- 数据库连接池了解吗, 有什么好处?
- 有了解数据库连接池吗?
- 自己如何设计数据库连接池
- 数据库连接池用的哪个? 数据库连接是线程安全的吗?
- MyBatis 中其实是有数据库连接池的,那么为什么要有数据库连接池?
- 为什么不可以来一个我就创建一个 JDBC 连接?
- 数据库连接池了解哪些
- 那单例我们一般用来做什么?
只需要一个对象的场景,比如数据库连接池、文件系统这种 会用线程池
-
数据库连接池用的什么,怎么配置的
-
数据库连接池是为了解决什么问题
-
数据库连接池 最大连接数、最小连接数
-
自己设计一个数据库连接池怎么设计;
-
数据库连接池介绍下,底层实现说下
-
数据库连接池具体内容,作用?线程池具体内容,作用?
-
数据库连接池讲一下,长时间没有用到的连接怎么处理。
-
如何使用数据库连接池
转载自【https://blog.csdn.net/NIUBILISI/article/details/100173513】
转载自【https://blog.csdn.net/shuaihj/article/details/14223015】
转载自【https://blog.csdn.net/CrankZ/article/details/82874158】
转载自【https://blog.csdn.net/qq_36528311/article/details/87264571】
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)