`

配置Tomcat 4.1.29的连接池

阅读更多

配置Tomcat 4.1.29的连接池
Tomcat 4.1.29是目前的最高稳定版本,下面介绍一下它的连接池配置方法。
1)    连接池配置(Database Connection Pool (DBCP) Configurations)
DBCP使用的是Jakarta-Commons Database Connection Pool 要使用连接池需要如下的组件即jar文件。
Jakarta-Commons DBCP 1.1 对应commons-dbcp-1.1.jar。
Jakarta-Commons Collections 2.0 对应commons-collections.jar。
Jakarta-Commons Pool 1.1 对应commons-pool-1.1.jar。
这三个jar文件要与你的JDBC驱动程序一起放到【TOMCAT_HOME】\common\lib目录下以便让tomcat和你的web应用都能够找到。
注:这三个jar文件是默认存在与【TOMCAT_HOME】\common\lib下的。
需要注意的地方:第三方的驱动程序或者其他类只能以*.jar的形式放到Tomcat的common\lib目录中,因为Tomcat只把*.jar文件加到CLASSPATH中。
不要把上诉三个文件放到WEB-INF/lib或者其他地方因为这样会引起混淆。

2)    通过配置阻止连接池漏洞
数据库连接池创建和管理连接池中建立好的数据库连接,循环使用这些连接以得到更好的效率。这样比始终为一个用户保持一个连接和为用户的请求频繁的建立和销毁数据库连接要高效的多。
这样就有一个问题出现了,一个Web应用程序必须显示的释放ResultSet,Statement和Connection。如果在关闭这些资源的过程中失败将导致这些资源永远不在可用,这就是所谓的连接池漏洞。这个漏洞最终会导致连接池中所有的连接不可用。
通过配置Jakarta Common DBCP可以跟踪和恢复那些被遗弃的数据库连接。
以下是一系列相关配置:
    通过配置DBCP数据源中的参数removeAbandoned来保证删除被遗弃的连接使其可以被重新利用。
为ResourceParams(见下文的数据源配置)标签添加参数removeAbandoned
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
通过这样配置的以后当连接池中的有效连接接近用完时DBCP将试图恢复和重用被遗弃的连接。这个参数的值默认是false。
    通过设置removeAbandonedTimeout来设置被遗弃的连接的超时的时间,即当一个连接连接被遗弃的时间超过设置的时间时那么它会自动转换成可利用的连接。
    <parameter>
     <name>removeAbandonedTimeout</name>
     <value>60</value>
     </parameter>
    默认的超时时间是300秒。
    设置logAbandoned参数,这个参数的用处我没能够理解它的意义所以提供原文供大家参考。
The logAbandoned parameter can be set to true if you want DBCP to log a stack trace of the code which abandoned the dB connection resources。
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>
这个参数默认为false。

3)    下面以MySQL为例演示Tomcat数据库连接池的配置
    MySQL的版本以及对应的JDBC驱动程序
MySQL 3.23.47, MySQL 3.23.47 using InnoDB, MySQL 4.0.1alpha对应的驱动为mm.mysql 2.0.14 (JDBC Driver)。
    在MySQL中创建供测试的数据库,表结构以及数据

mysql> create database javatest;
mysql> use javatest;
mysql> create table testdata (
    ->   id int not null auto_increment primary key,
    ->   foo varchar(25), 
    ->   bar int);
    mysql> insert into testdata values(null, 'hello', 12345);
Query OK, 1 row affected (0.00 sec)

mysql> select * from testdata;
+----+-------+-------+
| ID | FOO   | BAR   |
+----+-------+-------+
|  1 | hello | 12345 |
+----+-------+-------+
1 row in set (0.00 sec)



    要注意的是登录的mysql用户要有创建数据库的权限还有注意要设置密码我用的是root^_^。
    配置Tomcat的server.xml文件
配置【TOMCAT_HOME】\common\lib下的server.xml文件,在</host>标签之前加入以下内容以添加JNDI数据源:

xml 代码
  1. <Context path="/DBTest" docBase="DBTest"        debug="5" reloadable="true" crossContext="true">     
  2. <Logger className="org.apache.catalina.logger.FileLogger"             prefix="localhost_DBTest_log." suffix=".txt"             timestamp="true"/>     
  3. <Resource name="jdbc/TestDB"               auth="Container"               type="javax.sql.DataSource"/>     
  4. <ResourceParams name="jdbc/TestDB">       
  5. <parameter>         
  6. <name>factory</name>    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>       
  7. </parameter>       
  8. <!-- Maximum number of dB connections in pool. Make sure you         configure your mysqld max_connections large enough to handle         all of your db connections. Set to 0 for no limit.         -->       
  9. <parameter>         
  10. <name>maxActive</name>         
  11. <value>100</value>       
  12. </parameter>       
  13. <!-- Maximum number of idle dB connections to retain in pool.         Set to 0 for no limit.         -->       
  14. <parameter>         
  15. <name>maxIdle</name>         
  16. <value>30</value>       
  17. </parameter>       
  18. <!-- Maximum time to wait for a dB connection to become available         in ms, in this example 10 seconds. An Exception is thrown if         this timeout is exceeded.  Set to -1 to wait indefinitely.         -->       
  19. <parameter>         
  20. <name>maxWait</name>         
  21. <value>10000</value>       
  22. </parameter>       
  23. <!-- MySQL dB username and password for dB connections  -->       
  24. <parameter>        
  25. <name>username</name>        
  26. <value>javauser</value>       
  27. </parameter>       
  28. <parameter>        
  29. <name>password</name>        
  30. <value>javadude</value>       
  31. </parameter>       
  32. <!-- Class name for mm.mysql JDBC driver -->       
  33. <parameter>          
  34. <name>driverClassName</name>          
  35. <value>org.gjt.mm.mysql.Driver</value>       
  36. </parameter>       
  37. <!-- The JDBC connection url for connecting to your MySQL dB.         The autoReconnect=true argument to the url makes sure that the         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the         connection.  mysqld by default closes idle connections after 8 hours.         -->       
  38. <parameter>         
  39. <name>url</name>    
  40. <value>jdbc:mysql://localhost:3306/javatest?autoReconnect=true</value>       
  41. </parameter>     
  42. </ResourceParams>  
  43. </Context>  

    配置Web应用程序的web.xml文件
xml 代码
  1. <?xml version="1.0" encoding="ISO-8859-1"?>       
  2. <!DOCTYPE web-app PUBLIC    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"    "http://java.sun.com/dtd/web-app_2_3.dtd">  
  3. <web-app>     
  4. <description>MySQL Test App</description>     
  5. <resource-ref>         
  6. <description>DB Connection</description>         
  7. <res-ref-name>jdbc/TestDB</res-ref-name>         
  8. <res-type>javax.sql.DataSource</res-type>         
  9. <res-auth>Container</res-auth>     
  10. </resource-ref>  
  11. </web-app>  


    测试代码
测试代码包括一个JSP文件和一个Java类。代码如下:

xml 代码
    1. <html>    
    2.   <head>    
    3.     <title>DB Test</title>    
    4.   </head>    
    5.   <body>    
    6.   <%    
    7.     foo.DBTest tst = new foo.DBTest();    
    8.     tst.init();    
    9.   %>    
    10.   <h2>Results</h2>    
    11.     Foo <%= tst.getFoo() %><br>    
    12.     Bar <%= tst.getBar() %>    
    13.   </body>    
    14. </html>   
    package
     foo;
  1.  
  2. import javax.naming.*;
  3. import javax.sql.*;
  4. import java.sql.*;
  5.  
  6. public class DBTest {
  7.  
  8.   String foo = "Not Connected";
  9.   int bar = -1;
  10.     
  11.   public void init() {
  12.     try{
  13.       Context ctx = new InitialContext();
  14.       if(ctx == null ) 
  15.           throw new Exception("Boom - No Context");
  16.       DataSource ds = 
  17.             (DataSource)ctx.lookup(
  18.                "java:comp/env/jdbc/TestDB");
  19.       if (ds != null) {
  20.         Connection conn = ds.getConnection();     
  21.         if(conn != null)  {
  22.             foo = "Got Connection "+conn.toString();
  23.             Statement stmt = conn.createStatement();
  24.             ResultSet rst = 
  25.                 stmt.executeQuery(
  26.                   "select id, foo, bar from testdata");
  27.             if(rst.next()) {
  28.                foo=rst.getString(2);
  29.                bar=rst.getInt(3);
  30.             }
  31.             conn.close();
  32.         }
  33.       }
  34.     }catch(Exception e) {
  35.       e.printStackTrace();
  36.     }
  37.  }
  38.  public String getFoo() { return foo; }
  39.  public int getBar() { return bar;}
  40. }


最后在Tomcat的webapps目录下建立DBTest然后将应用程序文件拷贝到这个目录下即可。
    重新启动Tomcat在浏览器上http://localhost:8080/DBTest/test.jsp即可看到结果。
Results
Foo hello
Bar 12345

4)    一些常见的问题
    由于垃圾收集器的运行而导致连接超时
Tomcat是运行在JVM中的,JVM要周期性的执行GC(垃圾收集器)来清除不再被引用的Java对象。在GC运行时Tomcat将会冻结,如果在设置连接池中的连接的最大等待时间(MaxWait)小于GC的运行时间的话那么你很可能在使用数据库连接时失败。推荐将连接的超时时间设置成10到15秒。
注意连接的超时时间与被遗弃的连接的超时时间的区别。
    重复关闭连接引发的异常
这种情况发生在当响应一个客户的请求时从数据库连接池里取得了连接但是关闭了两次。使用连接池中的连接与使用直接与数据库建立的连接是不一样的,连接池中的连接在释放时只是将连接返回到连接池而不是释放连接的资源。Tomcat使用多线程来处理并发的请求,以下实例演示了一个在Tomcat中可以导致出错的过程:
请求A在线程A中运行并从连接池中得到一个连接
请求A关闭了这个连接
JVM转到线程B
请求B在线程B中运行并取得一个连接(这个连接是请求A刚刚返回的那个)
JVM转到线程A
请求A在finally块中又一次关闭连接(因为第一次没有设置连接引用为null)
JVM转到线程B
请求B试图使用得到的连接但连接已经被请求A返回到了连接池中所以请求B的操作失败
以下是一段公认的恰当的代码可以避免以上的问题

  1.   Connection conn = null;
  2.   Statement stmt = null;  // Or PreparedStatement if needed
  3.   ResultSet rs = null;
  4.   try {
  5.     conn = ... get connection from connection pool ...
  6.     stmt = conn.createStatement("select ...");
  7.     rs = stmt.executeQuery();
  8.     ... iterate through the result set ...
  9.     rs.close();
  10.     rs = null;
  11.     stmt.close();
  12.     stmt = null;
  13.     conn.close(); // Return to connection pool
  14.     conn = null;  // Make sure we don't close it twice
  15.   } catch (SQLException e) {
  16.     ... deal with errors ...
  17.   } finally {
  18.     // Always make sure result sets and statements are closed,
  19.     // and the connection is returned to the pool
  20.     if (rs != null) {
  21.       try { rs.close(); } catch (SQLException e) { ; }
  22.       rs = null;
  23.     }
  24.     if (stmt != null) {
  25.       try { stmt.close(); } catch (SQLException e) { ; }
  26.       stmt = null;
  27.     }
  28.     if (conn != null) {
  29.       try { conn.close(); } catch (SQLException e) { ; }
  30.       conn = null;
  31.     }
  32.   }


我个人认为以上的代码非常的安全,不过try块中释放资源的代码好像可以省略,不知到大家怎么看^_^
如果翻译和理解的有错误,欢迎大家批评指教^_^
来源于javaResearch

分享到:
评论

相关推荐

    图解ArcGIS 平台搭建说明

    图解ArcGIS 平台搭建说明,包括ArcGIS Desktop 安装配置,ArcSDE for Oracle9i 安装配置,ArcIMS安装配置(JDK1.4.2+Appach 2.0.48+Tomcat 4.1.29+ArcIMS 9.0),

    netty-all-4.1.29.Final-API文档-中英对照版.zip

    赠送jar包:netty-all-4.1.29.Final.jar; 赠送原API文档:netty-all-4.1.29.Final-javadoc.jar; 赠送源代码:netty-all-4.1.29.Final-sources.jar; 包含翻译后的API文档:netty-all-4.1.29.Final-javadoc-API...

    netty-all-4.1.29.Final-API文档-中文版.zip

    赠送jar包:netty-all-4.1.29.Final.jar; 赠送原API文档:netty-all-4.1.29.Final-javadoc.jar; 赠送源代码:netty-all-4.1.29.Final-sources.jar; 赠送Maven依赖信息文件:netty-all-4.1.29.Final.pom; 包含...

    netty-all-4.1.29.Final.jar最新版导入直接用

    本jar包为最新的netty-all-4.1.29c.jar 可导入直接用 Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架...

    FinalData-v4.1.29超强数据恢复软件

    FinalData-v4.1.29超强数据恢复软件

    netty-all-4.1.29.Final-javadoc.jar 压缩包

    Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers ...本jar包为最新的netty-all-4.1.29.Final-javadoc.jar 解压即可看到最新文档

    EL AND JSTL概述

    EL 全名为Expression Language,它原本是JSTL 1.0为方便...假若您所用的Container 只支持Servlet 2.3/JSP 1.2,如:Tomcat 4.1.29,您就不能在JSP 网页中直接使用EL,必须安装支持Servlet 2.4 / JSP 2.0 的Container

    EL基本手册

    EL全名为ExpressionLanguage,它原本是JSTL1.0为方便存取数据...假若您所用的Container只支持Servlet 2.3/JSP1.2,如:Tomcat 4.1.29,您就不能在JSP网页中 直接使用EL,必须安装支持Servlet 2.4 / JSP2.0的Container。

    Netty.4.1.29.Final

    Netty.4.1.29.Final 包含Jar包支持、Javadoc、Source。。

    netty-all-4.1.29.Final-sources.jar 最新版netty源码

    本jar包为最新的netty-all-4.1.29c.jar 可导入直接用 Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架...

    超牛数据恢复V4.1.29免费安装版

    超牛数据恢复软件是一款免费的数据恢复软件,支持误删文件、格式化、硬盘分区丢失导致的文件数据丢失,功能强大,易用性好、恢复成功率高。

    一键还原系统 v4.1.29.1.zip

    一键还原系统是一款简单实用的系统辅助软件。软件可以实现系统的备份、还原和重装。可以支持所有Windows系统,及各种新旧硬件(包括...内核更新到4.1.29,提升稳定性 修正部分电脑提示组件丢失的问题 一键还原系统截图

    finalData 注册码

    好多的东西哦,必须上传分享,希望大家喜欢哦

    spring-4.3.29合并包,整包,单包

    spring-4.3.29合并包,整包,单包

    netty-all-4.1.39.Final.jar

    android netty

    创客云商商城

    创客云商是移动互联网下新一代移动社交电商平台,致力于美丽健康产业的分享式购物平台。以“创业简单化、购物便捷化、社交多元化”的核心理念,将创业、购物、社交有机融合。平台甄选全球高品质的精品,首批入驻...

    顶尖数据恢复软件

    顶尖数据恢复软件,版本号:4.1.29,附带激活码。我是从网上买来的,共享给需要的朋友。

    C#全能速查宝典

    《C#全能速查宝典》共分为8章,分别介绍了C#语言基础、Windows窗体及常用控件、Windows高级控件、控件公共属性、方法及事件、数据库开发、文件、数据流与注册表、GDI+绘图技术和C#高级编程,共包含562个C#编程中常用...

    Tutorialize-crx插件

    4.1.30 ------检查器现在在class和id属性中转义了错误字符4.1.29 ------修复了删除教程的问题修复了问题,对话框每次显示时都显示对话框第4.1.28页------修复了jQuery UI的可拖动更改的错误4.1.27 --------------...

    UPnP_Programming_Guide

    Linux SDK for UPnP Devices v1.4 Contents 1 Introduction . ....2 License ....3 About Callbacks ....4 The API .... 4.1 Error codes .... 4.1.1 UPNP E SUCCESS [0] .... 4.1.2 UPNP E INVALID HANDLE [-100] ....

Global site tag (gtag.js) - Google Analytics