连接池原理解读,各个连接池对比

1.JDBC规范的实现

JDBC(Java DataBase Connectivity)是Java和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行SQL语句。它由一组用Java语言编写的类和接口组成。各种不同类型的数据库都有相应的实现。本文以Mysql实现为例。

1.1.JDBC编程模型

1.装载相应数据库的JDBC驱动并进行初始化;
2.建立JDBC和数据库之间的Connection连接;
3.创建Statement或者PreparedStatement接口;
4.执行SQL语句;
5.处理和显示结果;
6.释放资源
在这里插入图片描述

1.2.MySql对JDBC的实现

在我们学习JDBC的时候,我们就开始写代码连接数据库。那时候我们会写如下代码:

	@Test
	public void testDB() throws Exception {
		try {
			String dbUrl = "";
			String userName = "";
			String passWord = "";
			Class.forName("com.mysql.jdbc.Driver");
			Connection connection = DriverManager.getConnection(dbUrl,userName,passWord);
			Statement statement = connection.createStatement();
			String sql = "";
			statement.execute(sql);
			statement.close();
			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

写着写着,我们就会发现,这样写代码太繁琐了,每次我明明只是关注写String sql = “”;但是却要重复的编写加载驱动,获取连接,关闭连接等重复代码。于是我们可能会编写一个工具类,来帮我们完成这堆重复代码,并且考虑线程等问题。但是这样仅仅只是减少了我们的代码量,其背后网络资源、数据库的性能消耗更加值得我们关注。

1.3.传统JDBC带来的问题

1.3.1.网络资源问题

站在网络的角度上,当我们在传统的JDBC中,执行一个SQL语句时,我们需要如下几个阶段:
1.建立网络TCP
2.MySql连接认证
3.sql语句执行
4.MySql关闭连接
5.关闭TCP
流程示意图如下
在这里插入图片描述
通过流程示意图,我们发现,我们虽然仅仅只是编写SQL操作数据,却存在诸多网络操作。那么这个时候,性能肯定会受到网络资源的影响。假设已经有人帮我们建立了网络TCP,认证了数据库,而我们也不需要关心如何关闭连接,关闭网络。那对于我们操作数据库来说,性能是不是就得到了很大的提升?

1.3.2.并发访问资源问题

相信大家一定有这样的经历,去银行或者其他柜台办理业务的时候,如果办理业务的人数量小于正常办理业务的窗口,这时候是有空闲的窗口,我们不需要等待的。但是来办理业务的人数量大于窗口服务数量,这时候就需要取号排队等待了,随着办理业务的人员越来越多,最终等待的人原来越多,如果中间在遇到个别几个窗口不服务,那等待就更严重了。
数据库也一样,假设客户端发起了很多请求,但是服务端不能及时处理完这些请求,或者说,当请求数大于可用的处理数(数据库最大连接数),那就存在一些应用程序无法访问到数据库。
在这里插入图片描述

1.3.3.需要解决的问题

减少网络资源的消耗
控制客户端访问服务的请求数量

2.连接池

2.1.什么是数据库连接池

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

2.2.连接池原理

2.2.1.连接池的建立

连接池的工作原理主要由三部分组成:连接池的建立、连接池中连接的使用管理、连接池的关闭。
第一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。

2.2.2.连接的管理

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

2.2.3.连接的关闭

当应用程序退出(服务器关闭,宕机等情况)时,关闭连接池中所有的连接,释放连接池相关的资源。
程序调用close,并不是真正的关闭连接,而是将连接归还到连接池。

2.3.连接池的作用

2.3.1.资源重用

由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,增进了系统环境的平稳性(减少内存碎片以级数据库临时进程、线程的数量)

2.3.2.提升系统响应速度

数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池内备用。此时连接池的初始化操作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。

2.3.3.统一管理连接

数据库连接池负责创建、分配、管理和释放连接,能避免数据库连接泄露,并且检测有问题的连接。

3.连接池的发展

从连接池的发展来说,可以把连接池划分为第一、二代连接池。
第一代连接池:一般来讲采用单线程同步的架构设计都属于第一代连接池。
第二代连接池:采用多线程异步架构
先上图。
在这里插入图片描述

3.1.C3P0

一句话概括C3P0,死翘翘
国外是什么情况,这个博主不知道,不过国内C3P0确实已经被打入冷宫了,在很长一段时间内,它一直是Java领域内数据库连接池的代名词。就连当年牛逼轰轰的Hibernate(有幸在大三自学,现在毕业三年多了,但是从未参与过hibernate的项目)将其作为内置的数据库连接池。只不过后浪推前浪,在今天Hibernate一样死翘翘了。导致C3P0死翘翘的原因在于他的性能以及代码复杂度。哪怕在C3P0使用量最为巅峰的时期,其性能也是同期产品性能最垫底的。可能就是代码太过于复杂,导致官方于2015年放弃更新维护。本身就是性能最差的第一代连接池,在今天被打入冷宫实属正常。

3.2.DBCP

一句话概括DBCP,差点咸鱼翻身
DBCP(DataBase Connection Pool)属于Apache顶级项目Commons中的核心子项目。但DBCP并不是独立实现连接池功能的,它内部依赖于Commons中的另一个子项目Pool,连接池最核心的“池”,就是由Pool组件提供的,因此,DBCP的性能实际上就是Pool的性能。

换句话说,DBCP的命脉在Pool的手里

终于在tomcat 7.0版本中,tomcat重新设计开发出了一套连接池(Tomcat JDBC Pool)并且于13年9月发布了Commons-Pool 2.0。命脉已经更新的DBCP终于在14年2月份发布了DBCP2.0。但是,毕竟由于长时间没有更新突破的DBCP,已经被人放弃了。

3.3.Druid

阿里巴巴出品,借助于阿里这个平台的号召力,产品一经发布就赢得了大批用户的拥趸,从用户使用的反馈来看,Druid也确实没让用户失望。相较于其他产品,Druid另一个比较大的优势,就是中文文档比较全面。
Druid 相对于其他数据库连接池的优点
强大的监控特性,通过Druid提供的监控功能,可以清楚知道连接池和SQL的工作情况。
优点1. 监控SQL的执行时间、ResultSet持有时间、返回行数、更新行数、错误次数、错误堆栈信息;

优点2. SQL执行的耗时区间分布。什么是耗时区间分布呢?比如说,某个SQL执行了1000次,其中01毫秒区间50次,110毫秒800次,10100毫秒100次,1001000毫秒30次,1~10秒15次,10秒以上5次。通过耗时区间分布,能够非常清楚知道SQL的执行耗时情况;

优点3. 监控连接池的物理连接创建和销毁次数、逻辑连接的申请和关闭次数、非空等待次数、PSCache命中率等。

优点4.Druid提供了Filter-Chain模式的扩展API,可以自己编写Filter拦截JDBC中的任何方法,可以在上面做任何事情,比如说性能监控、SQL审计、用户名密码加密、日志等等。
Druid集合了开源和商业数据库连接池的优秀特性,并结合阿里巴巴大规模苛刻生产环境的使用经验进行优化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章