DBCP链接池介绍

DBCP链接池介绍

-----------------------------html

目前 DBCP 有两个版本分别是 1.3 和 1.4。java

DBCP 1.3 版本须要运行于 JDK 1.4-1.5 ,支持 JDBC 3。mysql

DBCP 1.4 版本须要运行于 JDK 1.6 ,支持 JDBC 4。web

1.3和1.4基于同一套源代码,含有全部的bug修复和新特性。所以在选择DBCP版本的时候,要看你用的是什么JDK版本。spring

DBCP1.2版本性能通常,比c3p0差挺多。DBCP1.4和1.3,配合(依赖)commons pool 1.6的jar包,各方面功能、性能推动到新的高峰。相对1.2版本提升很多。超越(或至关)了c3p0.建议使用DBCP1.4或1.3 +  commons pool 1.6sql

Tomcat7 中保留DBCP链接池,以兼容已有应用。并提供了新的Tomcat JDBC pool做为DBCP的可选替代。新出的Tomcat JDBC pool,听说比DBCP 1.4要好,未接触,也不在本文讨论范围内。数据库

DBCP链接池配置参数讲解

-----------------------------apache

1、Apache官方DBCP文档给出的配置示例:tomcat

可参见:http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html服务器

<Context>

  <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"

               maxActive="100" maxIdle="30" maxWait="10000"

               username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"

               url="jdbc:mysql://localhost:3306/javatest"/>

</Context>

2、经常使用参数说明:

可参见:http://elf8848.iteye.com/blog/337981

<Resource

name="jdbc/TestDB"  JNDI数据源的name

type="javax.sql.DataSource"

driverClassName="com.mysql.jdbc.Driver" JDBC驱动类

url=""

username="" 访问数据库用户名

password="" 访问数据库的密码

maxActive="80" 最大活动链接

initialSize="10"  初始化链接

maxIdle="60"   最大空闲链接

minIdle="10"   最小空闲链接

maxWait="3000" 从池中取链接的最大等待时间,单位ms.

    validationQuery = "SELECT 1"  验证使用的SQL语句

    testWhileIdle = "true"      指明链接是否被空闲链接回收器(若是有)进行检验.若是检测失败,则链接将被从池中去除.

    testOnBorrow = "false"   借出链接时不要测试,不然很影响性能

    timeBetweenEvictionRunsMillis = "30000"  每30秒运行一次空闲链接回收器

    minEvictableIdleTimeMillis = "1800000"  池中的链接空闲30分钟后被回收

    numTestsPerEvictionRun="3" 在每次空闲链接回收器线程(若是有)运行时检查的链接数量

    removeAbandoned="true"  链接泄漏回收参数,当可用链接数少于3个时才执行

    removeAbandonedTimeout="180"  链接泄漏回收参数,180秒,泄露的链接能够被删除的超时值

/>

DBCP链接池的自我检测

-----------------------------

默认配置的DBCP链接池,是不对池中的链接作测试的,有时链接已断开了,但DBCP链接池不知道,还觉得链接是好的呢。

应用从池中取出这样的链接访问数据库必定会报错。这也是好多人不喜欢DBCP的缘由。

问题例一:

MySQL8小时问题,Mysql服务器默认链接的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该 connection。

可是DBCP链接池并不知道链接已经断开了,若是程序正巧使用到这个已经断开的链接,程序就会报错误。

问题例二:

    之前还使用Sybase数据库,因为某种缘由,数据库死了后重启、或断网后恢复。

    等了约10分钟后,DBCP链接池中的链接还都是不能使用的(断开的),访问数据应用一直报错,最后只能重启Tomcat问题才解决 。

解决方案:

    方案一、定时对链接作测试,测试失败就关闭链接。

    方案二、控制链接的空闲时间达到N分钟,就关闭链接,(而后可再新建链接)。

    以上两个方案使用任意一个就能够解决以述两类问题。若是只使用方案2,建议 N <= 5分钟。链接断开后最多5分钟后可恢复。

    也可混合使用两个方案,建议 N = 30分钟。

    下面就是DBCP链接池,同时使用了以上两个方案的配置配置

    validationQuery = "SELECT 1"  验证链接是否可用,使用的SQL语句

    testWhileIdle = "true"      指明链接是否被空闲链接回收器(若是有)进行检验.若是检测失败,则链接将被从池中去除.

    testOnBorrow = "false"   借出链接时不要测试,不然很影响性能

    timeBetweenEvictionRunsMillis = "30000"  每30秒运行一次空闲链接回收器

    minEvictableIdleTimeMillis = "1800000"  池中的链接空闲30分钟后被回收,默认值就是30分钟。

    numTestsPerEvictionRun="3" 在每次空闲链接回收器线程(若是有)运行时检查的链接数量,默认值就是3.

    解释:

    配置timeBetweenEvictionRunsMillis = "30000"后,每30秒运行一次空闲链接回收器(独立线程)。并每次检查3个链接,若是链接空闲时间超过30分钟就销毁。销毁链接后,链接数量就少了,若是小于minIdle数量,就新建链接,维护数量很多于minIdle,过行了新老更替。

    testWhileIdle = "true" 表示每30秒,取出3条链接,使用validationQuery = "SELECT 1" 中的SQL进行测试 ,测试不成功就销毁链接。销毁链接后,链接数量就少了,若是小于minIdle数量,就新建链接。

    testOnBorrow = "false" 必定要配置,由于它的默认值是true。false表示每次从链接池中取出链接时,不须要执行validationQuery = "SELECT 1" 中的SQL进行测试。若配置为true,对性能有很是大的影响,性能会降低7-10倍。所在必定要配置为false.

    每30秒,取出numTestsPerEvictionRun条链接(本例是3,也是默认值),发出"SELECT 1" SQL语句进行测试 ,测试过的链接不算是“被使用”了,还算是空闲的。链接空闲30分钟后会被销毁。

DBCP链接池配置参数注意事项 

-----------------------------

maxIdle值与maxActive值应配置的接近。

由于,当链接数超过maxIdle值后,刚刚使用完的链接(刚刚空闲下来)会当即被销毁。而不是我想要的空闲M秒后再销毁起一个缓冲做用。这一点DBCP作的可能与你想像的不同。

若maxIdle与maxActive相差较大,在高负载的系统中会致使频繁的建立、销毁链接,链接数在maxIdle与maxActive间快速频繁波动,这不是我想要的。

高负载系统的maxIdle值能够设置为与maxActive相同或设置为-1(-1表示不限制),让链接数量在minIdle与maxIdle间缓冲慢速波动。

timeBetweenEvictionRunsMillis建议设置值

initialSize="5",会在tomcat一启动时,建立5条链接,效果很理想。

但同时咱们还配置了minIdle="10",也就是说,最少要保持10条链接,那如今只有5条链接,哪何时再建立少的5条链接呢?

一、等业务压力上来了, DBCP就会建立新的链接。

二、配置timeBetweenEvictionRunsMillis=“时间”,DBCP会启用独立的工做线程定时检查,补上少的5条链接。销毁多余的链接也是同理。

链接销毁的逻辑

------------------------------

DBCP的链接数会在  0 - minIdle - maxIdle - maxActive  之间变化。变化的逻辑描述以下:

默认未配置initialSize(默认值是0)和timeBetweenEvictionRunsMillis参数时,刚启动tomcat时,链接数是0。当应用有一个并发访问数据库时DBCP建立一个链接。

目前链接数量还未达到minIdle,但DBCP也不自动建立新链接已使数量达到minIdle数量(没有一个独立的工做线程来检查和建立)。

随着应用并发访问数据库的增多,链接数也增多,但都与minIdle值无关,很快minIdle被超越,minIdle值一点用都没有。

直到链接的数量达到maxIdle值,这时的链接都是只增不减的。 再继续发展,链接数再增多并超过maxIdle时,使用完的链接(刚刚空闲下来的)会当即关闭,整体链接的数量稳定在maxIdle但不会超过maxIdle。

但活动链接(在使用中的链接)可能数量上瞬间超过maxIdle,但永远不会超过maxActive。

这时若是应用业务压力小了,访问数据库的并发少了,链接数也不会减小(没有一个独立的线程来检查和销毁),将保持在maxIdle的数量。

默认未配置initialSize(默认值是0),但配置了timeBetweenEvictionRunsMillis=“30000”(30秒)参数时,刚启动tomcat时,链接数是0。立刻应用有一个并发访问数据库时DBCP建立一个链接。

目前链接数量还未达到minIdle,每30秒DBCP的工做线程检查链接数是否少于minIdle数量,若少于就建立新链接直到达到minIdle数量。

随着应用并发访问数据库的增多,链接数也增多,直到达到maxIdle值。这期间每30秒DBCP的工做线程检查链接是否空闲了30分钟,如果就销毁。但此时是业务的高峰期,是不会有长达30分钟的空闲链接的,工做线程查了也是白查,但它在工做。到这里链接数量一直是呈现增加的趋势。

当链接数再增多超过maxIdle时,使用完的链接(刚刚空闲下来)会当即关闭,整体链接的数量稳定在maxIdle。中止了增加的趋势。但活动链接(在使用中的链接)可能数量上瞬间超过maxIdle,但永远不会超过maxActive。

这时若是应用业务压力小了,访问数据库的并发少了,每30秒DBCP的工做线程检查链接(默认每次查3条)是否空闲达到30分钟(这是默认值),若链接空闲达到30分钟,就销毁链接。这时链接数减小了,呈降低趋势,将从maxIdle走向minIdle。当小于minIdle值时,则DBCP建立新链接已使数量稳定在minIdle,并进行着新老更替。

配置initialSize=“10”时,tomcat一启动就建立10条链接。其它同上。

minIdle要与timeBetweenEvictionRunsMillis配合使用才有用,单独使用minIdle不会起做用。

Tomcat中配置DBCP链接池

-----------------------------

Tomcat自带DBCP的包,是$CATALINA_HOME/lib/tomcat-dbcp.jar。

tomcat-dbcp.jar含有commons pool、commons DBCP两个包的内容。但只含有与链接池有关的类。

数据源配置在context.xml文件中, 要在tomcat的lib目录中放jdbc 驱动包

数据源配置在server.xml的host中,不须要在tomcat的lib目录中放jdbc 驱动包,只使用工程中的jdbc驱动包

JNDI配置:更改tomcat的server.xml或context.xml

    全局的数据源:

    若是须要配置全局的 Resource,则在server.xml的GlobalNamingResources节点里加入Resource,再在Context节点里加入ResourceLink的配置。

    全局的resource只是为了重用,方便全部该tomcat下的web工程的数据源管理,但若是你的tomcat不会同时加载多个web工程,也就是说一个tomcat只加载一个web工程时,是没有必要配置全局的resource的。

每一个web工程一个数据源:

在$CATALINA_HOME/conf/context.xml的根节点Context里加入Resource配置。这种配置方法,你在context.xml配置了一个数据源,但Tomcat中有同时运行着5个工程,那了就坏事儿了,这个在Tomcat启动时数据源被建立了5份,每一个工程1份数据源。链接数会是你配置的参数的5倍。

只有在你的Tomcat只加载一个web工程时,才能够直接以context.xml配置数据源。

<Resource name="jdbc/testDB"       //指定的jndi名称,会用于spring数据源bean的配置和ResourceLink的配置

               type="javax.sql.DataSource"   //数据源床型,使用标准的javax.sql.DataSource

               driverClassName="com.mysql.jdbc.Driver"    //JDBC驱动器

               url="jdbc:mysql://localhost:3306/test" //数据库URL地址            

               username="test"     //数据库用户名

               password="test"   //数据库密码

               maxIdle="40"   //最大的空闲链接数

               maxWait="4000" //当池的数据库链接已经被占用的时候,最大等待时间

               maxActive="40" //链接池当中最大的数据库链接

               removeAbandoned="true"

               removeAbandonedTimeout="180"

               logAbandoned="true" //被丢弃的数据库链接是否作记录,以便跟踪

               factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" />

      这里的factory指的是该Resource 配置使用的是哪一个数据源配置类,这里使用的是tomcat自带的标准数据源Resource配置类,这个类也能够本身写,实现javax.naming.spi.ObjectFactory 接口便可。某些地方使用的commons-dbcp.jar中的org.apache.commons.dbcp.BasicDataSourceFactory,若是使用这个就需把commons-dbcp.jar及其依赖的jar包,都放在tomcat的lib下,光放在工程的WEB-INF/lib下是不够的。

     ResourceLink 的配置有多种:

     1)tomcat安装目录下的conf/context.xml,把全局的resource直接公开给该tomcat下的全部web工程,在Context节点中加入:

<ResourceLink global="jdbc/testMDB" name="jdbc/testMDB" type="javax.sql.DataSource"/>  

不建议在此文件中,不使用<ResourceLink/>,而使用<Resource/>直接配置数据源,缘由上面已说明了。  

     2)tomcat安装目录下的conf/server.xml,该方法能够指定把哪些source绑定到哪一个web工程下。

<!-- 新增,第一行为加载的工程配置,第二行是该工程须要的ResourceLink配置 -->

<context docBase="/web/webapps/phoenix" path="" reloadable="false">

      <ResourceLink global="jdbc/testMDB" name="jdbc/testMDB" type="javax.sql.DataSource"/>

</context>

也可在此文件中,不使用<ResourceLink/>,而使用<Resource/>直接配置数据源。

     3)安装目录下的conf/localhost/下创建一个xml文件,文件名是<yourAppName>.xml。好比工程名为test,则该xml名为test.xml。

<?xml version="1.0" encoding="UTF-8"?>

<Context>  

    <ResourceLink global="jdbc/testMDB" name="jdbc/testMDB" type="javax.sql.DataSource"/>      

</context>

也可在此文件中,不使用<ResourceLink/>,而使用<Resource/>直接配置数据源。

     4)tomcat安装目录下的\webapps\test\META-INF\context.xml的Context节点中增长:

<ResourceLink global="jdbc/testMDB" name="jdbc/testMDB" type="javax.sql.DataSource"/>

也可在此文件中,不使用<ResourceLink/>,而使用<Resource/>直接配置数据源。

本文内容都在tomcat6.0上运行测试过,还下载了commons DBCP的源码,加入了跟踪日志,用于验证本文的理论。

链接池排名(纯我的见解)

-----------------------------

Tomcat JDBC pool

DBCP 1.4

c3p0   速度不错

BoneCP 速度不错,但会启用不少附加线程作回收、关闭工做。

Proxool 在高并发时出现异常

DBCP 1.2

DBPool 最差,垫底。

参考文档《Java链接池评估报告》

相关文章
相关标签/搜索