数据层优化-jdbc连接池简述、druid简介

终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和dao层的优化去写,本篇是一个开始。本文会介绍连接池技术并对比目前比较流行的java连接池技术,之后,会把druid整合到项目中来,将技术方案落地,实际整合到项目中,让技术能为我所用。

使用连接池的原因

jdbc的demo

//第一步,注册驱动程序
//com.MySQL.jdbc.Driver
Class.forName("数据库驱动的完整类名");
//第二步,获取一个数据库的连接
Connection conn = DriverManager.getConnection("数据库地址","用户名","密码");
//第三步,创建一个会话
Statement stmt=conn.createStatement();
//第四步,执行SQL语句
stmt.executeUpdate("SQL语句");
//或者查询记录
ResultSet rs = stmt.executeQuery("查询记录的SQL语句");
//第五步,对查询的结果进行处理
while(rs.next()){
//操作
}
//第六步,关闭连接
rs.close();
stmt.close();
conn.close();

对上面几行代码,大家不会陌生,这可能是我们初学jdbc连接时最熟悉的代码了,虽然现在可能用到了一些数据层ORM框架,但是底层实现依然如同上面代码一样,只是做了一些封装而已。这种方式也有一些不足,在与mysql进行数据交互时每次都需要新建connection资源,用完后关闭掉Connection资源,这种做法是非常浪费资源的,如果抬杠的话,可能有人会说,我就喜欢这种方式,我服务器配置足够好,我一点都不担心什么资源不资源,那你牛逼。

浪费资源这种说法是相对而言的,如果在小型项目中或者项目与数据库的交互不那么频繁的话,数据库连接的创建与关闭也不见得会把资源浪费多少,亦或者在项目启动时期,我们可能只考虑功能实现,就直接copy一份现成的数据库集成代码过来用,这种做法都是很正常的现象,本阶段的内容主要是项目优化,那么关注点肯定就不是项目初始时期,也不去讨论硬件配置有多好,而是针对目前代码中的不足进行优化,找到一个相对较好的优化方案,并落实到项目中去,今天我们讲的优化方案就是使用连接池技术代替目前与数据库的交互方式。

为什么在连接数据库时要使用连接池?
数据库连接是一种关键的有限的昂贵的资源,一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的性能低下。

数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,简单的说,就是在一个"池"里放了好多半成品的数据库连接对象,由应用程序动态地对池中的连接进行申请、使用和释放等操作。

连接池技术尽可能多地重用了消耗内存地资源,大大节省了内存,提高了服务器的服务效率,减少了程序与数据库交互时的部分开销,显著的改善应用程序的性能,通过使用连接池,提高了程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。

连接池的工作原理

连接池技术的核心思想是连接复用(也是我们在前一篇文章中提到的资源重用),通过建立一个数据库连接池以及一套连接使用、分配和管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。

连接池的工作原理主要由三部分组成,分别为连接池的建立、连接池中连接的使用管理、连接池的关闭:

  • 第一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。
  • 第二、连接池的管理。连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:
  • 当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;
  • 如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;
  • 如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。
  • 当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。

    该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。

  • 第三、连接池的关闭。当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。

连接池的优点及流行的连接池技术

对于连接池的优点,通过前文描述,我们也能得出以下结论:

  • 减少连接创建时间。连接池中的连接是已准备好的、可重复使用的,获取后可以直接访问数据库,因此减少了连接创建的次数和时间。
  • 简化的编程模式。当使用连接池时,每一个单独的线程能够像创建一个自己的JDBC连接一样操作,允许用户直接使用JDBC编程技术。
  • 控制资源的使用。如果不使用连接池,每次访问数据库都需要创建一个连接,这样系统的稳定性受系统连接需求影响很大,很容易产生资源浪费和高负载异常。连接池能够使性能最大化,将资源利用控制在一定的水平之下。连接池能控制池中的连接数量,增强了系统在大流量冲击下的稳定性。

流行的Java连接池:

  • C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
  • DBCP (Database Connection Pool)是一个依赖Jakarta commons-pool对象池机制的数据库连接池,Tomcat的数据源使用的就是DBCP。目前 DBCP 有两个版本分别是 1.3 和 1.4。1.3 版本对应的是 JDK 1.4-1.5 和 JDBC 3,而1.4 版本对应 JDK 1.6 和 JDBC 4。因此在选择版本的时候要看看你用的是什么 JDK 版本了,功能上倒是没有什么区别。
  • Proxool是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能
  • Druid是阿里开源的一个数据库连接池技术,号称是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

对比下来,最终选择了Druid连接池,接下来也会将Druid技术整合到目前的项目中去,C3P0和DBCP都用过,也碰到一些问题,总体来说,功能中规中矩,比直接操作jdbc方式要好的多,但是对比与Druid的话就有些不足了,因为Druid是在目前市面上流行的连接池技术的基础上开发出来的,你有的Druid有,你没有的Druid也能提供,Druid不仅仅是一个高效可管理的数据库连接池,它还有一套基于Filter-Chain模式的插件体系,也内置SQLParser功能,同时还能监控数据库访问性能,可以作为监控来使用,总结起来就是高效、功能强大、可扩展性好。

总结:目前的问题及解决方案

目前ssm-demo项目中与mysql服务器的交互使用的是Spring自带的一个工具类,DriverManagerDataSource,配置文件如下:

<!-- 配置数据源 -->
    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url"
                  value="jdbc:mysql://127.0.0.1:3306/ssm_db?useUnicode=true&amp;characterEncoding=UTF-8  "/>
       <property name="username" value="root"/>
        <property name="password" value="admin"/>
    </bean>

DriverManagerDataSource建立连接的作法是只要有连接就新建一个connection,根本没有连接池的作用,也就是说文章前面所提到的资源消耗的弊端还是存在的,但是我们觉察不出来,感觉项目也挺正常的。这是因为目前网站的访问量较小,与mysql数据库的交互不频繁,由于访问量小,对后端的请求就少,因此mysql查询就少,压力也不会大,项目体量及访问总量都很小,就更别提数据库的QPS了,根本不值一提,也就是说现有的网站形势下,根本不会对mysql数据库产生任何的压力,根本不会有死锁的产生,根本不会有事务锁的产生,根本不会有数据库资源耗尽情况的产生,也根本不会有数据库服务器崩掉的产生.....

但是如果网站的访问量大了起来,功能丰富了起来,用户访问量增长了起来,是目前的10000倍、100000倍甚至更大的情况下,各种问题就随之而来了,当然,这么多问题出现了,我们是不是修改了数据连接池就好了?肯定不是,数据库连接池仅仅解决了数据层的部分问题,对性能有一部分的提升,它不能解决掉网站演进过程中的各种问题,别想太多,因为过程中会出现各种各样的问题,项目也会暴露出各个方面的不足,前端、后端、运维、DBA、架构....等等维度都有可能出现问题,需要不同的方案和不同的技术来优化,不要想着一劳永逸。

OK,可能有点扯远了,还是说回到连接池,下一篇文章会介绍阿里的Druid连接池技术并将其整合到项目中,待续。

时间: 2024-10-29 19:12:00

数据层优化-jdbc连接池简述、druid简介的相关文章

JDBC连接池概述

Reference Source:https://www.progress.com/tutorials/jdbc/jdbc-jdbc-connection-pooling 介绍 本文档提供的信息旨在帮助开发人员为必须处理连接池的应用程序提供连接池策略. 首先, 本文档提供 jdbc 3.0 规范指定的 jdbc 连接池概述. 接下来, 它提供了一些示例, 说明如何使用 DataDirect 连接池管理器 (它随 DataDirect Connect?用于jdbc 和 DataDirect Seq

号称性能最好的JDBC连接池:HikariCP

HikariCP号称是现在性能最好的JDBC连接池组件,具体的性能到底如何,我也没有仔细的测试过,不过从它现在的发展来看,其可能确实如它宣传的那样其性能高过目前所有的连接池组件.之前对连接池的记忆一直都是C3P0.DBCP.BoneCP,这三者中BoneCP的性能是最好的,C3P0的性能在现在来说确实是非常差的了,好像C3P0很久都没有更新了,所以我们应该杜绝在项目中使用C3P0,至于是否要使用HikariCP,我觉得可以尝试.HikariCP毕竟是才出来不久,其性能到底如何,也需要实践的检验,

JDBC连接池的简单实现

先说明一下,我本身是做android开发的,java web是我的弱项,只是近来京东云免费,于是去折腾了几下,有了些许经验,特作分享.如果文章中内容有误,还请各高手指正. 我在web端,需要连接数据库进行查询插入等操作,但是每次进行操作都先获取连接用完后就断开的话,未免效率太低.以前知道tomcat中可以配置,但是京东云引擎的tomcat并不能由自己配置.因为我折腾的东西较小,所以也不考虑使用框架,于是就想自己写一个. 我写的连接池很简单,在初始化时创建5个连接,并放在一个列表当中.如果要获取连

使用了Tomcat JDBC连接池不能重连的问题

在项目中用到了tomcat 的jdbc连接池,发现一个问题是,当数据库重启时,服务没有重新的去连接数据库,需要将部署的项目重新启动才能连接到数据库.经过测试对配置做一下修改: 在配置dataSource的地方加入两个配置属性: <property name="testOnBorrow" value="true"/> <!--在连接返回给调用者前用于校验连接是否有效的SQL语句,如果指定了SQL语句,则必须为一个SELECT语句,且至少有一行结果--

JDBC连接池C3P0

连接池 1)传统方式找DriverManager要连接,数目是有限的. 2)传统方式的close(),并没有将Connection重用,只是切断应用程序和数据库的桥梁,即无发送到SQL命令到数据库端执行 3)项目中,对于Connection不说,不会直接使用DriverManager取得,而使用连接池方式. 4)DBCP和C3P0,都是Java开源的,都必须直接或间接实现javax.sql.DataSource接口 5)DBCP连接池需要dbcp.properties文件,同时需加入3个对应的j

Spring boot (11) tomcat jdbc连接池

默认连接池 tomcat jdbc是从tomcat7开始推出的一个连接池,相比老的dbcp连接池要优秀很多,spring boot将tomcat jdbc作为默认的连接池,只要在pom.xml中引入了spring boot的jdbc组件,就会自动引入tomcat jdbc连接池. 默认参数 以下是org.apache.tomcat.jdbc.pool.PoolProperties源码,这是tomcat jdbc连接池的默认初始参数.这个类实现了一个接口PoolConfiguration,查看这个

Java之JDBC连接池

数据库连接池 连接池的概述 概念:其实就是一个容器(集合),存放数据库连接的容器. 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时, 从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器. 好处: 节约资源 用户访问高效 实现: 标准接口:DataSource javax.sql包下的 方法: 获取连接:getConnection() 归还连接:Connection.close().如果连接对象Connection是从连接池中获取的,那么调用Connecti

MySql &amp; JDBC &amp; 连接池 &amp; 总结

连接池:解决资源浪费,提高代码性能. 本小节目标: 使用DBCP,C3P0连接池完成基本数据库的操作. 使用DBUtils完成CRUD的操作. 数据库连接池的解决方案是: 当应用程序启动时,系统主动建立足够的数据库连接,并将这些连接组成一个连接池.每次应用程序请求数据库连接时,无须重新打开连接,而是从连接池中取出已有的连接使用,使用完后不再关闭数据库连接,而是直接将连接归还给连接池.通过使用连接池,将大大提高程序的运行效率. 数据库连接池是Connection 对象的工程.数据库连接池的常用参数

JDBC连接池与工具类

1.连接池概述 用池来管理Connection,这样可以重复使用Connection,有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象,当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection归还给池,池就可以再利用这个Connection对象了 2.C3P0 public class Demo1 { @Test public void test() throws Ex