数据库连接池详解

Posted 亮哥的IT职场

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库连接池详解相关的知识,希望对你有一定的参考价值。

一:应用程序直接获取数据库连接的缺点

用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。如下图所示:



二:使用数据库连接池优化程序性能

数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正式针对这个问题提出来的.数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。如下图所示:



 数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中, 这些数据库连接的数量是由最小数据库连接数来设定的.无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量.连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中.



 三:开源数据库连接池


现在很多WEB服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。

在使用了数据库连接池之后,在项目的实际开发中就不需要编写连接数据库的代码了,直接从数据源获得数据库的连接。


目前数据库连接池产品是非常多的,DBCP、C3P0、Proxool等都是非常优秀的产品。


Hibernate开发组推荐使用c3p0,spring开发组推荐使用dbcp。


(1)DBCP数据源

DBCP 是 Apache 软件基金组织下的开源连接池实现,要使用DBCP数据源,需要应用程序应在系统中增加如下两个 jar 文件:

Commons-dbcp.jar:连接池的实现

Commons-pool.jar:连接池实现的依赖库

Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。


在配置时,不常用但在生产环境中很有用的参数有:removeAbandoned 、removeAbandonedTimeout、maxWait。


如果设置了rmoveAbandoned=true,那么在getNumActive()快要到getMaxActive()的时候,系统会进行无效的Connection的回收,回收的 Connection为removeAbandonedTimeout(默认300秒)中设置的秒数后没有使用的Connection。 


如果设置了logAbandoned=true,DBCP将会在回收Connection之后,打印回收Connection的错误信息,包括在哪个地方用了Connection却忘记关闭了这样的信息,在调试的时候很有用。 


基本配置如下: 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  

<property name="driverClassName" value="${db.driverClassName}"/>  

<property name="url" value="${db.url}"/>  

<property name="username" value="${db.username}"/>  

<property name="password" value="${db.password}"/>  

<!--initialSize: 初始化连接-->  

<property name="initialSize" value="5"/>  

<!--maxIdle: 最大空闲连接-->  

<property name="maxIdle" value="10"/>  

<!--minIdle: 最小空闲连接-->  

<property name="minIdle" value="5"/>  

<!--maxActive: 最大连接数量-->  

<property name="maxActive" value="15"/>  

<!--removeAbandoned: 是否自动回收超时连接-->  

<property name="removeAbandoned" value="true"/>  

<!--removeAbandonedTimeout: 超时时间(以秒数为单位)-->  

<property name="removeAbandonedTimeout" value="180"/>  

<!--maxWait: 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒-->  

<property name="maxWait" value="3000"/>  

<property name="validationQuery">  

<value>SELECT 1</value>  

</property>  

<property name="testOnBorrow">  

<value>true</value>  

</property>  

</bean>  



maxActive是最大激活连接数,这里取值为15,表示同时最多有15个数据库连接。

maxIdle是最大的空闲连接数,这里取值为10,表示即使没有数据库连接时依然可以保持10空闲的连接,而不被清除,随时处于待命状态。

MaxWait是最大等待秒钟数,如果取值-1,表示无限等待,直到超时为止。这里取3000,表示3秒后超时。


注意:在设置这些参数的时候,需要考虑mysql的最大连接数:

查询方法:show variables like '%max_connections%'; 

修改方法:

vi /etc/my.cnf

max_connections = 800

service mysqld restart 


(2)C3P0数据源


C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。C3P0数据源在项目开发中使用得比较多。

c3p0与dbcp区别:

dbcp没有自动回收空闲连接的功能

c3p0有自动回收空闲连接功能


<c3p0-config>

<!--

C3P0的缺省(默认)配置,

如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源

-->

<default-config>

<property name="driverClass">com.mysql.jdbc.Driver</property>

<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy</property>

<property name="user">root</property>

<property name="password">XDP</property>


<property name="acquireIncrement">5</property>

<property name="initialPoolSize">10</property>

<property name="minPoolSize">5</property>

<property name="maxPoolSize">20</property>

</default-config>


<!--

C3P0的命名配置,

如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”这样写就表示使用的是name是MySQL的配置信息来创建数据源

-->

<named-config name="MySQL">

<property name="driverClass">com.mysql.jdbc.Driver</property>

<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy</property>

<property name="user">root</property>

<property name="password">XDP</property>


<property name="acquireIncrement">5</property>

<property name="initialPoolSize">10</property>

<property name="minPoolSize">5</property>

<property name="maxPoolSize">20</property>

</named-config>

</c3p0-config>


连接池的性能和稳定性会对我们的程序造成极大的影响,因此,有必要对这些连接池产品进行一些选择。另外,连接池的配置是否恰当,将会决定该连接池的性能和稳定性表现。

以上是关于数据库连接池详解的主要内容,如果未能解决你的问题,请参考以下文章

面试题:数据库连接池原理详解与自定义连接池实现

Java中数据库连接池原理机制详解面试+提高

数据库连接池两种配置方式详解

Druid 数据库连接池 详解

Java数据库连接池详解

详解C3P0(数据库连接池)