序言
我参与的这些项目都用到了数据库连接池,这自然是有它的原因的。有时候我们可能会忘了当初为什么使用了某种设计模式或者某项技术,因此很有必要从头再推理一遍。每项技术或者技术决策肯定都有它的优势和劣势,如果发现它没有缺点的话,那你最好仔细想想是不是漏掉了什么。
数据库连接的生命周期
数据库的每一个读写操作都需要有一个连接。我们来看下数据库连接的调用流是什么样的:
调用流程是这样的:
1. 应用程序的数据访问层请求DataSource来获取一个数据库连接。
2. DataSource使用数据库驱动来打开一个数据库连接。
3. 创建数据库连接,同时打开了一个TCP socket。
4. 应用程序进行数据库的读写。
5. 连接已经不再需要了,因此关闭它。
6. 关闭socket。
很容易可以看到,数据库连接的打开和关闭是非常昂贵的。PostgreSQL会为每个客户端连接分配一个单独的操作系统进程,因此高频率的打开关闭操作会使你的数据库管理系统负担很重。
重用数据库连接最主要的原因是:
1. 减少应用程序与数据库之间创建/销毁TCP连接的开销
2. 减少JVM的垃圾对象。
池还是非池
我们来将不用连接池的实现和HikariCP进行对比,HikariCP应该是最高效的连接池框架了。
测试程序会创建并关闭1000个连接。
图中显示的是打开及关闭连接所花费的时间,当然这个时间越短则越好。
使用了连接池的实现要比没有连接池快600倍。我们的企业级系统中有大量的应用,光是一个批处理的系统每小时就会创建两百万的数据库连接,因此像这样两个数量级差距的优化当然是应该考虑的。
为什么连接池如此高效?
要明白为什么连接池的性能会这么好,我们需要分析下连接池的调用流:
每当请求一个连接的时候,使用了连接池的数据源都会先通过连接池来获取一个新的连接。连接池只有当没有可用的连接并且还没有达到连接池上限的时候才会去创建新的连接。而连接池的close()方法只是把连接扔回到池里而已,并不是真的要关闭它。
更快,更安全
连接池扮演了连接请求的一个有界缓冲区的角色。如果流量瞬间出现了抖动连接池会使它变得平缓,而不是去耗尽所有的数据库资源。
等待超时的机制就像一个安全挂钩,它避免数据库服务器出现过高的负载。如果有个应用想要使用了过多的数据库资源,连接池会减缓它的调用,以免它将数据库压垮了(这样整个企业系统都会受到影响)。
能力越大,责任越大
所有的这些好处都是有代价的,连接池的配置又带来了额外的复杂性(尤其在大型的企业级应用中)。因此有了它并不能就高枕无忧了,你还得去注意连接池的许多配置项,比如:
1. 连接的最小数量
2. 连接池的最大数量
3. 最长空闲时间
4. 获取连接超时时间
5. 超时的重试次数
我的下一篇文章将会深入介绍企业级应用中数据库连接池面临的一个挑战,同时介绍下Flexy Pool是如何帮助你找到合适的连接池大小的。
代码在Github上可以下载。
原创文章转载请注明出处:http://it.deepinmind.com
我参与的这些项目都用到了数据库连接池,这自然是有它的原因的。有时候我们可能会忘了当初为什么使用了某种设计模式或者某项技术,因此很有必要从头再推理一遍。每项技术或者技术决策肯定都有它的优势和劣势,如果发现它没有缺点的话,那你最好仔细想想是不是漏掉了什么。
数据库连接的生命周期
数据库的每一个读写操作都需要有一个连接。我们来看下数据库连接的调用流是什么样的:
调用流程是这样的:
1. 应用程序的数据访问层请求DataSource来获取一个数据库连接。
2. DataSource使用数据库驱动来打开一个数据库连接。
3. 创建数据库连接,同时打开了一个TCP socket。
4. 应用程序进行数据库的读写。
5. 连接已经不再需要了,因此关闭它。
6. 关闭socket。
很容易可以看到,数据库连接的打开和关闭是非常昂贵的。PostgreSQL会为每个客户端连接分配一个单独的操作系统进程,因此高频率的打开关闭操作会使你的数据库管理系统负担很重。
重用数据库连接最主要的原因是:
1. 减少应用程序与数据库之间创建/销毁TCP连接的开销
2. 减少JVM的垃圾对象。
池还是非池
我们来将不用连接池的实现和HikariCP进行对比,HikariCP应该是最高效的连接池框架了。
测试程序会创建并关闭1000个连接。
- private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceConnectionTest.class);
- private static final int MAX_ITERATIONS = 1000;
- private Slf4jReporter logReporter;
- private Timer timer;
- protected abstract DataSource getDataSource();
- @Before
- public void init() {
- MetricRegistry metricRegistry = new MetricRegistry();
- this.logReporter = Slf4jReporter
- .forRegistry(metricRegistry)
- .outputTo(LOGGER)
- .build();
- timer = metricRegistry.timer("connection");
- }
- @Test
- public void testOpenCloseConnections() throws SQLException {
- for (int i = 0; i < MAX_ITERATIONS; i++) {
- Timer.Context context = timer.time();
- getDataSource().getConnection().close();
- context.stop();
- }
- logReporter.report();
- }
图中显示的是打开及关闭连接所花费的时间,当然这个时间越短则越好。
使用了连接池的实现要比没有连接池快600倍。我们的企业级系统中有大量的应用,光是一个批处理的系统每小时就会创建两百万的数据库连接,因此像这样两个数量级差距的优化当然是应该考虑的。
类型 | 不使用连接池的情况 | 使用了连接池的情况 |
最短时间 | 74.551414 | 0.002633 |
最长时间 | 146.69324 | 125.528047 |
平均时间 | 78.216549 | 0.128900 |
标准差 | 5.9438335 | 3.969438 |
中位数 | 76.150440 | 0.003218 |
为什么连接池如此高效?
要明白为什么连接池的性能会这么好,我们需要分析下连接池的调用流:
每当请求一个连接的时候,使用了连接池的数据源都会先通过连接池来获取一个新的连接。连接池只有当没有可用的连接并且还没有达到连接池上限的时候才会去创建新的连接。而连接池的close()方法只是把连接扔回到池里而已,并不是真的要关闭它。
更快,更安全
连接池扮演了连接请求的一个有界缓冲区的角色。如果流量瞬间出现了抖动连接池会使它变得平缓,而不是去耗尽所有的数据库资源。
等待超时的机制就像一个安全挂钩,它避免数据库服务器出现过高的负载。如果有个应用想要使用了过多的数据库资源,连接池会减缓它的调用,以免它将数据库压垮了(这样整个企业系统都会受到影响)。
能力越大,责任越大
所有的这些好处都是有代价的,连接池的配置又带来了额外的复杂性(尤其在大型的企业级应用中)。因此有了它并不能就高枕无忧了,你还得去注意连接池的许多配置项,比如:
1. 连接的最小数量
2. 连接池的最大数量
3. 最长空闲时间
4. 获取连接超时时间
5. 超时的重试次数
我的下一篇文章将会深入介绍企业级应用中数据库连接池面临的一个挑战,同时介绍下Flexy Pool是如何帮助你找到合适的连接池大小的。
代码在Github上可以下载。
原创文章转载请注明出处:http://it.deepinmind.com
相关推荐
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接池技术。某一应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。 在较为完备的数据库连接池实现中,可根据...
C# 数据库连接池 C# 数据库连接池 C# 数据库连接池 C# 数据库连接池
达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,
context.xml, 数据库连接池配置文
数据库连接池的例子.doc数据库连接池的例子.doc数据库连接池的例子.doc
Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置...
C#高效数据库连接池源码
* 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字 * 支持多线程,保证获取到的连接一定是没有被其他线程正在使用 * 按需创建连接,可以创建多个连接,可以控制连接的数量 * 连接...
提供了数据库连接池的驱动,分别有c3p0、druid、dbcp三种数据库连接池的驱动
Druid为监控而生的数据库连接池,它是阿里巴巴开源平台上的一个项目。Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能.它可以替换DBCP和C3P0连接池。Druid提供了一个高效、功能强大、可...
数据库连接池 数据库连接池 数据库连接池 数据库连接池
收集了常见的数据库连接jar包,包括oracle、mysql、sql server、db2、opta、dbcp连接池、c3p0连接池等等常见的数据库jar包,不断更新中。
这个文档详细讲述了mysql数据库连接池的配置以及数据库连接池的工作原理。
c#语言下,使用netcore2.1框架,调用netstandard数据库连接池组件
比较实用的几种数据库连接池详细配置,值得收藏
java开发,数据库连接池c3p0所需jar包。
数据库连接池-jar包 数据库连接池-jar包 数据库连接池-jar包 数据库连接池-jar包 数据库连接池-jar包 数据库连接池-jar包 数据库连接池-jar包 数据库连接池-jar包
JAVA 使用数据库连接池连接Oracle数据库,全代码,附加详细说明
数据库连接池的基础学习,针对mysql数据库的数据库连接池在java中的具体实现及应用配置
基于tp5的swoole支持,对th5的connection进行改造,使用Swoole\Coroutine\MySQL重写了基于swoole的PDO接口,实现了mysql的数据库连接池,本地测试可用。使用时,替换thinkphp/library/think/db/Connection.php,并...