共计 5800 个字符,预计需要花费 15 分钟才能阅读完成。
这篇文章将为大家详细讲解有关数据库连接池 dbcp 的原理及配置是怎样的,文章内容质量较高,因此丸趣 TV 小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
1. 简介
DBCP(DataBase Connection Pool), 数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用 dbcp 需要 3 个包:common-dbcp.jar,common-pool.jar,common-collections.jar 由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。
dbcp 提供了数据库连接池可以在 spring,iBatis,hibernate 中调用 dbcp 完成数据库连接,框架一般都提供了 dbcp 连接的方法;
tomcat 中也提供了 dbcp 的 jndi 设置方法,也可以不在框架中使用 dbcp,单独使用 dbcp 需要 3 个包:common-dbcp.jar,common-pool.jar,common-collections.jar
2. 连接池扼要
JDBC 是一套通用的 Java 语言与多种数据库(文件)通讯的标准 API。大部分针对数据库服务器(例如 Oracle, MySQL 等等)的 JDBC 实现都是基于 TCP/IP 连接的客户端 - 服务器端通讯方式。
当我们需要执行一个数据库操作时,有下面三步:
1. 客户端与服务器之间建立一个数据库连接
2. 执行某种数据库操作
3. 断开连接
如果每次处理都要走上面的三步,则应用程序与数据库服务器都要将大量的时间和资源消耗在数据连接的断开与建立上。对于某些数据库系统,一个数据库连接就是一个进程,而且数据库连接通常要占用不少资源,如排序区 /Join 区等等。对于并发较大的系统,建立一次连接然后缓存起来连续使用,直到程序结束等情况下再释放连接,就能够将系统资源集中在对数据库操作的处理上,从而大大提高性能。通常情况下将数据连接的建立和断开委托给一种能够数据库连接池的组件或服务进行管理。而 DBCP, C3p0, Proxool 等都是常用的开源的连接池组件。
就好像 A 公司在郊外,他们公司附近没有出租车。如果 A 公司有人要出去办事,他必须打电话给出租公司订车,用完车后他还要付账报销。 这样每个人出去一趟都必须订车、退车和报销。员工的很多时间白白花费在这上面了。于是 A 公司跟出租车公司定了一个合同,出租车公司给了他们一个车队。要用车随时去楼下找车队就可以了,用完了也不必结帐,A 公司统一跟出租车公司订车和结帐。这个车队就好比连接池,由公司(应用程序)来统一向出租车公司(数据库服务器)订车(建立连接)和退车(关闭连接)。
3.DBCP 的配置参数以及背后的原理
Commons-dbcp 连接池的配置参数比较多,也比较复杂,主要分为
· Jdbc 连接参数(username, password, url, driverClassName, connectionProperties )
· 事务处理参数 (defaultAutoCommit, defaultReadOnly, defaultTransactionIsolation, defaultCatalog)
· 连接池参数(详见下文)
· 连接池中链接存活性测试参数(详见下文)
· 预处理查询池化参数(poolPreparedStatements, maxOpenPreparedStatements)
· 丢弃失效链接相关参数(详见下文)以及一个控制是否可以正常情况下处于访问连接池包装下的底层 JDBC 链接参数(accessToUnderlyingConnectionAllowed)
其中 Jdbc 链接参数、事务处理都跟连接池关系不大,另预处理查询池化参数本文不详细叙述。有关 commons-dbcp 的详细参数配置信息请参考官方文档。
4. 连接池的配置
再用车队来比喻,出租车公司每提供一辆车给 A 公司,A 公司肯定要付出一定费用。这时候维持车队的大小就很重要了,在项目少用车少的时候,车队肯定要减少,不然很多空闲车辆也要付出成本;在项目多用车多的时候,肯定要扩大车队,不然车不够用,车队忙不过来。A 公司可以简单地设地两个阀值来动态调节车队中空闲的车辆数目以满足动态需求,一个是最小空闲车辆数 (最小空空闲连接数(minIdle),当剩余的空车数目小于该数目时,A 公司就向出租车公司请求加入新车。 一个是最大空闲车辆数(maxIdle),当剩余的车大于该数目时,就将刚刚用用完的车还给出租车公司从而减少车队数量。
另外,这家出租车公司可能要为多个客户服务,要考虑能够提供给 A 公司的最大的车数量,不能超过某个数量 (maxActive)。所以 A 公司想出租车申请新车时首先要看下当前正在用的车辆数目是否超过了这个最大数目,如果没有超过那就直接申请新车,否则可以让申请者(应用程序中执行请求的线程)等待 (maxWait =0, 无限等待; maxWait 0 当等待时间超过 maxWait 时,失败)。
在连接池中,这几个参数是十分重要的,官方的说明如下,是我们调节系统性能时需要认真考虑的值。
Parameter
Default
Description
initialSize
0
The initial number of connections that are created when the pool is started.
Since: 1.2
线程池启动时初始化的连接数
maxActive
8
The maximum number of active connections that can be allocated from this pool at the same time, or non-positive for no limit.
最大活动连接数,如果非正整数,则不做限制。
maxIdle
8
The maximum number of connections that can remain idle in the pool, without extra ones being released, or negative for no limit.
最大空闲连接数。
minIdle
0
The minimum number of connections that can remain idle in the pool, without extra ones being created, or zero to create none.
最小空闲连接数。
maxWait
indefinitely
The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception, or -1 to wait indefinitely.
(在没有连接可用时)连接池等待一个数据连接可用时的以毫秒计的最大等待时间,超时以后抛出异常, -1 则将无限等待
实际上,Dbcp 依赖于 commons-pool 来存储连接对象。 BasicDataSource 默认使用 GenericObjectPool 来管理连接对象。除了请求的线程会在请求和返回连接过程中影响池中连接实例外,另有一个跑着 GenericObjectPool.Evictor 类型 (implements Runnable) 的实例的线程,也会影响池中的数据库连接。
5. 使用注意点
1) 如果 maxIdle 设置太低,在高负载系统中,连接的打开时间比关闭的时间快,会引起连接池中的 idle 的个数上升超过 maxIdle,造成频繁的销毁和创建,类似于 jvm 参数中的 Xmx 设置。
2) minIdle,该参数越接近 maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的,但是不能太大,因为在机器很空闲的时候,也会创建低于 minIdle 个数的连接,类似于 jvm 参数中的 Xms 设置。
3) PreparedStatements 会在数据库中保持打开的游标, 这样会造成一个连接超出数据库游标限制, 特别是当 maxOpenPreparedStatements 被设置成 default (unlimited),并且应用在一个连接上创建了大量不同 PreparedStatements 时,为了避免这个问题, maxOpenPreparedStatements 应该设置为一个小于数据库在一个连接上允许打开最大游标数。
4) poolPreparedStatements,经过测试,开启后的性能没有关闭的好,或者相差不大,没有本质的提高。
5) 对性能影响比较大的两个参数:
testOnBorrow:这个默认的之是 true,对性能影响很大,因为每次从池中借出对象时进行一次验证,系统开销很大,实际测试中发现,性能差距有 7 -10 倍的样子。
maxIdle:如果这个参数的值比 maxActive 低,在高负载的情况下就会产生很多 time_waited 线程。根据我们的测试结果,这个值最好和 maxActive 相同或者是设成 -1。这样才能在高并发下,应用到数据库的连接也是稳定的使用固有的 connection。否则 dbcp 会频繁创建新的连接,丢弃老的连接。而创建连接这个操作,比验证还要昂贵。
由于将 maxIdle 设置了一个比较高的值,应用就会在系统高峰时期创建的连接就会维持在那里。在空闲的时候这些连接就显得有些浪费。很多的时候数据库机器可能会支持多个应用,或者一个集群可能会有很多台应用机器。为了能这些空闲连接能够回收,就必须设置着一个配置项。这个值和 minEvictableIdleTimeMillis 以及 numTestsPerEvictionRun 会影响 evictor thread 的行为。默认 timeBetweenEvictionRunsMillis 的值是 -1,就是不会运行。但是如果它设了一个不为 - 1 的值,那么 minEvictableIdleTimeMillis 就不能设置的太短,默认的 30 分钟是个不错的选择。
6. 配置样例
bean id=“dataSource” >
property name=“driverClassName” value=“${db_driverClassName}” /
property name=“url” value=“${db_rul}” /
property name=“username” value=”${db_user}” /
property name=“password” value=”${db_passwd}” /
property name=“maxActive” value=”${db_maxActive }” /
property name=“initialSize” value=”${db_initialSize}” /
property name=“maxWait” value=”${db_maxWait}” /
property name=“maxIdle” value=”${db_maxIdle }” /
property name=“minIdle” value=”${db_minIdle}” /
property name= timeBetweenEvictionRunsMillis value= 30000 /
property name= testOnBorrow value= false /
property name= testWhileIdle value= true /
property name= validationQuery value= select 1 from dual /
property name=“removeAbandoned” value=”true” /
property name=“removeAbandonedTimeout” value=”180” /
/bean
7.Mysql 数据库的配置:
?xml version= 1.0 encoding= UTF-8 ?
beans
xmlns= http://www.springframework.org/schema/beans
xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance
xmlns:p= http://www.springframework.org/schema/p
xsi:schemaLocation= http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
bean id= dataSource >
property name= driverClassName
value com.mysql.jdbc.Driver /value
/property
property name= url
value jdbc:mysql://localhost:3306/booksystem /value
/property
property name= username
value root /value
/property
property name= password
value mysqladmin /value
/property
property name= maxActive
value 10 /value
/property
property name= initialSize
value 2 /value
/property
/bean
/beans
关于数据库连接池 dbcp 的原理及配置是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。