序言
我参与的这些项目都用到了数据库连接池,这自然是有它的原因的。有时候我们可能会忘了当初为什么使用了某种设计模式或者某项技术,因此很有必要从头再推理一遍。每项技术或者技术决策肯定都有它的优势和劣势,如果发现它没有缺点的话,那你最好仔细想想是不是漏掉了什么。
数据库连接的生命周期
数据库的每一个读写操作都需要有一个连接。我们来看下数据库连接的调用流是什么样的:
调用流程是这样的:
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#数据库连接池是一种管理数据库连接的技术,通过复用已存在的连接而不是每次请求时都创建新的连接,从而提高数据库操作的...
数据库连接池是现代应用程序开发中的重要组成部分,尤其是在处理大量数据交互的应用中,它极大地提高了数据库操作的效率和系统的稳定性。本资源"03-数据库连接池驱动"包含了三种常用的数据库连接池驱动:C3P0、Druid...
数据库连接池在初始化时会创建一定数量的数据库连接并保存起来,当应用程序需要连接时,可以从池中获取一个已存在的连接,而不是每次都去新建,用完后也不立即关闭,而是归还给连接池。这样可以显著减少建立和释放...
Java JDBC 数据库连接池总结 Java 语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁。在 Web 应用开发的早期,主要使用的技术是 CGIASPPHP 等。之后,Sun 公司推出了基于 Java 语言的 ...
数据库连接池是一种资源管理技术,它预先创建并维护一定数量的数据库连接,当应用需要时,可以从池中获取连接,使用完毕后归还而不是直接关闭,从而减少了频繁创建和销毁连接的开销。在.NET Core中,对于MySQL数据库...
context.xml, 数据库连接池配置文
* 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字 * 支持多线程,保证获取到的连接一定是没有被其他线程正在使用 * 按需创建连接,可以创建多个连接,可以控制连接的数量 * 连接...
达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,
数据库连接池在Java中的实现是提高应用程序性能的关键技术之一,它通过复用已存在的数据库连接,避免了频繁创建和销毁连接导致的系统资源浪费。本文将深入探讨如何使用Java代码来实现一个简单的数据库连接池,并解释...
数据库连接池是Java开发中非常重要的一个组件,它在处理多线程环境下对数据库资源的高效利用和管理中起着关键作用。C3P0是一个开源的Java连接池实现,它提供了一种灵活且功能强大的数据库连接管理方式。在本文中,...
Java 数据库连接池是 Java 应用程序中用于管理数据库连接的重要工具,它极大地提高了应用程序的性能和效率。本文将详细介绍如何在 Java 中实现一个完整的数据库连接池,并探讨其核心概念、工作原理以及如何根据需求...
MySQL数据库连接池是提高应用程序性能的一种重要技术,它允许开发者管理多个数据库连接并高效地复用这些连接,而不是每次需要时都创建新的连接。在C#编程中,我们可以使用自定义的连接池或者第三方库如ADO.NET的...
数据库连接池是数据库管理系统中的一个重要概念,主要用于优化数据库的连接操作。在C#编程中,数据库连接池可以高效地管理数据库连接,避免频繁创建和销毁连接导致的性能开销。本文将详细介绍C#中数据库连接池的工作...
数据库连接池是现代应用程序中管理数据库连接的一种高效方式,它能显著提高系统性能,减少资源消耗。在给定的标题“配置数据库连接池”中,我们可以深入探讨数据库连接池的概念、工作原理,以及如何配置Oracle9i和...