tomcat jdbc pool

文中内容主要转自:http://www.open-open.com/lib/view/open1327478028639.html 

                               http://www.open-open.com/lib/view/open1365991769687.html     

                               http://blog.csdn.net/lzm1340458776/article/details/37901619

tomcat jdbc pool 可在 Tomcat 中直接使用,也可以在独立的应用中使用。

 

属性说明:

name 数据源名称,这个随便,通常取为jdbc/XXX的格式
auth Container容器
type javax.sql.DataSource 注意是javax不是java
username 数据库用户名
password 数据库用户密码
maxIdle

连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,

连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置) 

maxActive 连接池的最大数据库连接数。设为0表示无限制。
maxWait 等待连接的最大连接的时间。最大等待毫秒数, 单位为 ms, 超过时间会出错误信息
driverClassName 数据库完整的驱动类全称。
url 数据库链接

 

 

 

 

 

 

 

 

 

 

 

1. 在独立应用中使用:

 1 import java.sql.Connection;
 2 import java.sql.ResultSet;
 3 import java.sql.Statement;
 4  
 5 import org.apache.tomcat.jdbc.pool.DataSource;
 6 import org.apache.tomcat.jdbc.pool.PoolProperties;
 7  
 8 public class SimplePOJOExample {
 9  
10     public static void main(String[] args) throws Exception {
11     PoolProperties p = new PoolProperties();
12     p.setUrl("jdbc:mysql://localhost:3306/mysql");
13     p.setDriverClassName("com.mysql.jdbc.Driver");
14     p.setUsername("root");
15     p.setPassword("password");
16     p.setJmxEnabled(true);
17     p.setTestWhileIdle(false);
18     p.setTestOnBorrow(true);
19     p.setValidationQuery("SELECT 1");
20     p.setTestOnReturn(false);
21     p.setValidationInterval(30000);
22     p.setTimeBetweenEvictionRunsMillis(30000);
23     p.setMaxActive(100);
24     p.setInitialSize(10);
25     p.setMaxWait(10000);
26     p.setRemoveAbandonedTimeout(60);
27     p.setMinEvictableIdleTimeMillis(30000);
28     p.setMinIdle(10);
29     p.setLogAbandoned(true);
30     p.setRemoveAbandoned(true);
31     p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
32       "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
33     DataSource datasource = new DataSource();
34     datasource.setPoolProperties(p);
35  
36     Connection con = null;
37     try {
38       con = datasource.getConnection();
39       Statement st = con.createStatement();
40       ResultSet rs = st.executeQuery("select * from user");
41       int cnt = 1;
42       while (rs.next()) {
43           System.out.println((cnt++)+". Host:" +rs.getString("Host")+
44         " User:"+rs.getString("User")+" Password:"+rs.getString("Password"));
45       }
46       rs.close();
47       st.close();
48     } finally {
49       if (con!=null) try {con.close();}catch (Exception ignore) {}
50     }
51     }
52  
53 }

 

2. 在 Tomcat 中直接使用

    方式一、

    1). 找到tomcat所在目录中的conf文件夹中的context.xml文件,在其中做修改(在Context结点里面添加):         

 1 <!—mysql数据源配置-->  
 2     <Resource  
 3        name="ds_mysql"  
 4        auth="Container"  
 5        type="javax.sql.DataSource"  
 6        maxActive="100"  
 7        maxIdel="30"  
 8        maxWait="10000"  
 9        username="root"  
10        password="5982285"  
11        driverClassName="com.mysql.jdbc.Driver"  
12        url="jdbc:mysql://localhost/myblog"  
13     />  
14     <!—oracle数据源配置-->  
15     <Resource  
16        name="jdbc/oracleds"  
17        auth="Container"  
18        type="javax.sql.DataSource"  
19        maxActive="100"  
20        maxIdel="30"  
21        maxWait="10000"  
22        username="scott"  
23        password="tiger"  
24        driverClassName="oracle.jdbc.driver.OracleDriver"  
25        url="jdbc:oracle:thin:@localhost:1521:sky"  
26     /> 

 

注:上面为mysql和Oracle配置了数据源,看个人需求而定,二者选其一。

注:网上很多人都说需要在web.xml文件中再次配置,其实不配置也是可以的(本人就没有在web.xml配置,依然跑的很溜),另外有一个要

       特别注意的是要将数据源的jar包和数据库的驱动包放到tomcat的lib包中。

 

JNDI技术简介

JNDI(Java Naming and Directory Interface)即Java命名和目录接口,它对应于Java EE中的javax.naming包,这套API的主要作用:它可以

把DataSource对象放在一个Tomcat容器中(JNDI容器),并为容器中的DataSource对象取一个名称,以后程序想获得DataSource对象,只需

要通过名称检索即可。

JNDI的核心API为Context,它代表JNDI容器,核心方法是lookup()它的功能是检索容器中对应名称的对象。

 

连接池工具类:

 1 /** 
 2  * 获取数据库连接的工厂 
 3  * @author Liao 
 4  */  
 5 public class ConnectionFactory {  
 6   
 7     private static DataSource dataSource;  
 8       
 9     static {  
10         try {  
11             //初始化查找命名空间  
12             Context context = new InitialContext();  
13             //找到DataSource。 java:/comp/env为固定路径。  ds_mysql是tomcat中设置的数据源  
14             dataSource = (DataSource) context.lookup("java:comp/env/ds_mysql");  
15         } catch (Exception e) {  
16             e.printStackTrace();  
17         }  
18     }  
19       
20     /** 
21      * 获取数据库连接 
22      */  
23     public static Connection getConnection(){  
24         try {  
25             //通过数据源获取连接然后返回  
26             return dataSource.getConnection();  
27         } catch (Exception e) {  
28             e.printStackTrace();  
29             return null;  
30         }  
31     }  
32       
33     /** 
34      * 关闭资源 
35      * @param conn 
36      * @param sta 
37      * @param res 
38      */  
39     public static void closeConnection(Statement sta, ResultSet res) {  
40         try {  
41             if (res != null) {  
42                 res.close();  
43                 res = null;  
44             }  
45             if (sta != null) {  
46                 sta.close();  
47                 sta = null;  
48             }  
49   
50         } catch (SQLException e) {  
51             e.printStackTrace();  
52         }  
53     }  
54 }  

注:上述程序,没有关闭连接,是因为用完连接之后,连接又回到了连接池,处于空闲状态。       

     java:/comp/env为固定路径。  ds_mysql是tomcat中设置的数据源

 

连接池配置常见错误:
Invalid byte 1 of 1-byte UTF-8 sequence.

原因:

在context.xml文件中使用了中文的注释(这个确实比较坑爹,但确实是这样的)。

解决方案:

把中文的注释去掉即可。 

 

方式二、

    1). 在conf/server.xml下的<GlobalNamingResources>节点里配置resource,例如:         

 1 <Resource name="jdbc/ens"
 2       auth="Container"
 3       type="javax.sql.DataSource"
 4       factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
 5       testWhileIdle="true"
 6       testOnBorrow="true"
 7       testOnReturn="false"
 8       validationInterval="30000"
 9       timeBetweenEvictionRunsMillis="30000"
10       maxActive="100"
11       minIdle="10"
12       maxWait="10000"
13       initialSize="10"
14       removeAbandonedTimeout="60"
15       removeAbandoned="true"
16       logAbandoned="true"
17       minEvictableIdleTimeMillis="30000"
18       jmxEnabled="true"
19       jdbcInterceptors=
20 "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
21       username="root"
22       password="123"
23       driverClassName="com.mysql.jdbc.Driver"
24       url="jdbc:mysql://localhost:3306/ens"/>

然后,在context.xml文件的<Context></Context>节点中添加如下配置:

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

global="jdbc/ens" 中的参数值("jdbc/ens")必须和上一段<Resource >配置中的name属性的值保持一样。name="jdbc/ens" 这个可以随便取,

但是在程序中调用的时候,就应该与name的值保持一致。到这里,连接池已经配置好啦。用JSP测试一下:

 1 <%@ page language="java" pageEncoding="gbk"%>
 2 <%@page import="java.sql.Connection"%>
 3 <%@page import="javax.naming.Context"%>
 4 <%@page import="javax.naming.InitialContext"%>
 5 <%@page import="javax.sql.DataSource"%>
 6 <%@page import="java.sql.Statement"%>
 7 <%@page import="java.sql.ResultSet"%>
 8 <%
 9    //连接池的获取
10     Connection conn = null;
11     DataSource ds = null;
12     ResultSet rs  =null;
13     Statement stmt = null;
14     Context initCtx = new InitialContext();
15     ds =(DataSource)initCtx.lookup("java:comp/env/jdbc/ens");
16    if(ds!=null){
17         out.println("已经获得DataSource!");
18         out.println("<br>");
19         conn = ds.getConnection();
20        try{
21         stmt = conn.createStatement();
22         String sql ="select * from ens_area";
23         rs = stmt.executeQuery(sql);
24         out.println("以下是从数据库中读取出来的数据:<br>");
25             while(rs.next()){
26                 out.println("<br>");
27                 out.println(rs.getString("area_name"));
28             }
29        }catch(Exception ex){
30          ex.printStackTrace();
31        }finally{
32           conn.close();
33           rs.close();
34           stmt.close();
35        }
36    }
37 %>

 

参数介绍:

1. initialSize :连接池启动时创建的初始化连接数量(默认值为0)  

2. maxActive :连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)  

3. maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,

    连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置)  

4. minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;

    但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置)  

5. maxWait  :最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因

    线程池不够用,而导致请求被无限制挂起) 

6. poolPreparedStatements:开启池的prepared(默认是false,未调整,经过测试,开启后的性能没有关闭的好。)  

7. maxOpenPreparedStatements:开启池的prepared 后的同时最大连接数(默认无限制,同上,未配置)  

8. minEvictableIdleTimeMillis  :连接池中连接,在时间段内一直空闲, 被逐出连接池的时间  

9.(默认为30分钟,可以适当做调整,需要和后端服务端的策略配置相关)  

10. removeAbandonedTimeout  :超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180)  

11. removeAbandoned  :超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收(默认为false,调整为true)

 

 

数据库重连机制,参考文章:

http://agapple.iteye.com/blog/791943

http://agapple.iteye.com/blog/772507

http://lc87624.iteye.com/blog/1734089

 

posted @ 2015-02-13 10:15  Jtianlin  阅读(2152)  评论(0编辑  收藏  举报