web项目在tomcat中使用dbcp的连接池管理技术实现:
第一步:将数据库的驱动jar包放到tomcat的lib文件夹中,因为tomcat已经自带了dbcp的相关jar包tomcat-dbcp.jar,就无需另外添加了。
第二步:打开tomcat的conf文件夹中的context.xml文件,将文件中相应的context标签修改成如下代码:
<Context>
<!--表示服务器会监视应用的WEB-INF/web.xml 文件来知道那个应用会引用在此处定义的资源。-->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<!--name 指定Resource的JNDI名称 ,注意这里的名字,在java代码中和项目的web.xml文件中需要使用到-->
<!--auth 指定管理Resource的Manager(Container:由容器创建和管理|Application:由Web应用创建和管理)-->
<!--type 指定Resource所属的Java类-->
<!--initialSize 初始化连接-->
<!--maxActive 指定连接池中处于活动状态的数据库连接的最大数目-->
<!--maxIdle 指定连接池中处于空闲状态的数据库连接的最大数目-->
<!--minIdle 最小数目-->
<!--maxWait 指定连接池中的连接处于空闲的最长时间,超过这个时间会抛出异常,取值为-1,表示可以无限期等待超时等待时间以毫秒为单位6000毫秒/1000等于60秒 -->
<!--removeAbandoned 是否自动回收超时连接-->
<!--logAbandoned 是否在自动回收超时连接的时候打印连接的超时错误-->
<!--removeAbandonedTimeout 超时时间(以秒数为单位)-->
<!--type 指定Resource所属的Java类-->
<!--这里还有一份高人编写参数设置的说明:
maxActive="100"
表示并发情况下最大可从连接池中获取的连接数。如果数据库不是单独,供一个应用使用,通过设置maxActive参数可以避免某个应用无限制的获取连接对其他应用造成影响,如果一个数据库只是用来支持一个应用那么maxActive理论上可以设置成该数据库可以支撑的最大连接数。maxActive只是表示通过连接池可以并发的获取的最大连接数。连接的获取与释放是双向,当应用程序并发请求连接池时,连接池就需要从数据库获取连接,那么但应用程序使用完连接并将连接归还给连接池时,连接池是否也同时将连接归还给数据库呢?很显然答案是否定的,如果那样的话连接池就变得多此一举,不但不能提高性能,反而会降低性能,那么但应用成归还连接后,连接池如何处理呢?
maxIdle="30"
如果在并发时达到了maxActive=100,那么连接池就必须从数据库中获取100个连接来供应用程序使用,当应用程序关闭连接后,由于maxIdle=30,因此并不是所有的连接都会归还给数据库,将会有30个连接保持在连接池种中,状态为空闲。
minIdle=”2”
最小默认情况下并不生效,它的含义是当连接池中的连接少有minIdle,系统监控线程将启动补充功能,一般情况下我们并不启动补充线程。
问题:如何设置maxActive和maxIdle?
理论上讲maxActive应该设置成应用的最大并发数,这样一来即便是在最大并发的情况下,应用依然能够从连接池中获取连接,但是困难时的是我们很难准确估计到最大并发数,设置成最大并发数是一种最优的服务质量保证,事实上,如果某个用户登录提示系统繁忙,那么在他再次登录时,可能系统资源已经充足,对于拜特资金管理系统我们建议将maxActive设置为系统注册人数的十分之一到二十分之一之间。例如系统的注册人数为1000,那么设置成50-100靠近100的数字,例如85或90。
maxIdle对应的连接,实际上是连接池保持的长连接,这也是连接池发挥优势的部分,理论上讲保持较多的长连接,在应用请求时可以更快的响应,但是过多的连接保持,反而会消耗数据库大量的资源,因此maxIdle也并不是越大越好,同上例我们建议将 maxIdle设置成50-100中靠近50的数字,例如55。这样就能在兼顾最大并发同时,保持较少的数据库连接,而且在绝大多情况,能够为应用程序提供最快的相应速度。
removeAbandoned="true"
removeAbandonedTimeout="60"
logAbandoned="true"
有时粗心的程序编写者在从连接池中获取连接使用后忘记了连接的关闭,这样连池的连接就会逐渐达到maxActive直至连接池无法提供服务。现代连接池一般提供一种“智能”的检查,但设置了removeAbandoned="true"时,当连接池连接数到达(getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)时便会启动连接回收,那种活动时间超过removeAbandonedTimeout="60"的连接将会被回收,同时如果logAbandoned="true"设置为true,程序在回收连接的同时会打印日志。removeAbandoned是连接池的高级功能,理论上这中配置不应该出现在实际的生产环境,因为有时应用程序执行长事务,可能这种情况下,会被连接池误回收,该种配置一般在程序测试阶段,为了定位连接泄漏的具体代码位置,被开启,生产环境中连接的关闭应该靠程序自己保证
-->
<Resource
name="jdbc/mysql5"
auth="Container"
type="javax.sql.DataSource"
initialSize="10"
maxActive="80"
maxIdle="20"
minIdle="1"
maxWait="10000"
removeAbandoned="true"
logAbandoned="true"
removeAbandonedTimeout="180"
username="root"
password="1"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/jack" />
</Context>
第三步:在项目中的web.xml文件中 添加如下配置:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/mysql5</res-ref-name> <!--引用的事tomcat的context.xml文件中配置的名称-->
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
第四步:简单编写一个测试代码如下:
package com.action;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
/*
* 这是一个测试servlet
*/
public class ActionServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
/*
类InitialContext
java.lang.Object
javax.naming.InitialContext
此类是执行命名操作的初始上下文。
所有命名操作都相对于某一上下文。该初始上下文实现 Context 接口并提供解析名称的起始点。
*/
Context ctx=new InitialContext();
//通过JNDI查找javax.sql.DataSource
DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/mysql5");
Connection conn=ds.getConnection();
System.out.println("conn----"+conn);
ResultSet rs = conn.prepareStatement("select * from student").executeQuery();
while(rs.next()){
System.out.println(rs.getInt(1)+"-----"+rs.getString(2));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我的机器上测试是正常的 tomcat 7 ,其他版本暂未测试!