Tomcat 5.5.23 文档阅读Tips 8 - JNDI Datasource
2011-01-11 22:31
381 查看
本文特别对Datasource类型的JNDI的配置做了解说。
1. Tomcat对DataSource类型的资源采用的是DBCP。DBCP支持JDBC 2.0, 在安装了JVM 1.4版本或更高的情况下,DBCP支持JDBC 3.0。
2. DBCP需要以下三个component,他们都来自Apache Jakarta Common Project,他们是:
Jakarta-Commons DBCP
Jakarta-Commons Collections
Jakarta-Commons Pool
这三个component都被包装在了$CATALINA_HOME/common/lib/naming-factory-dbcp.jar这个jar文件中。
3. Preventing DB Pool leaks. 这个很不错,DBCP为了防止应用程序忘记关闭ResultSets,Statements, Connections,特意设计了这样一个功能。DBCP能帮我们关闭不活动的connections,而且还能打印出stack trace,报告说是哪个class使用了connection,却没有关闭它。具体配置如下:
在定义DataSource的Resource定义中,加入attribute定义:
removeAbandoned="true"
这个属性默认配置为false。这样DBCP就可以关闭那些可能被应用程序忘记关闭的connection,具体的timeout设定这样配置:
removeAbandonedTimeout="60"
也就是说,如果DBCP发现一个connection 60秒内处于不活动状态,DBCP便自动回收。这个配置的默认值是300秒,也就是5分钟。
此外,还可以加入这个属性定义:
logAbandoned="true"
这样DBCP就会打印stack trace,让我们看到是哪个class忘记关闭connection。这个属性默认配置为false。
4. 文档给出了一个MySQL DataSource配置的例子。
(1) 将mysql jdbc的jar包放到$CATALINA_HOME/common/lib目录下。目前MySQL提供的官方驱动是Connector/J,目前EasyCluster中使用的是Connector/J 3.1.12版本,可以稳定工作。
(2) 在Tomcat中配置DataSource资源,以下例子给出的是在Context中的配置,也就说,只能给这个web app使用:
CODE: SELECT ALL
(3) 配置web.xml
CODE: SELECT ALL
(4) OK, 书写测试代码:
CODE: SELECT ALL
5. Common Problems I. 第一个常见问题就是“间歇性的取connection失败”。Tomcat分析说这是由于GC导致的。也就说,当GC发生的时候,Tomcat处于停止状态,如果GC花费的时间过长,长到超过了DBCP中配置的maxWait的时间,这种问题就会出现。DBCP中的maxWait表示的是当超过这个时间后,DBCP就认为取connection失败,这个值用毫秒表示。加入GC花费了15秒的时间(当然一般GC如果花费了10s就表示已经很恐怖了),而maxWait设定成10s的话,就会出现上面的问题了。解决方案是启动tomcat的时候加上-verbose:gc参数,观察每次gc花费的时间,然后微调maxWait或其他东西。
6. Common Problems II. Random Connection Close Exception. 这种问题EasyCluster中没有,他是这样产生的:
(1) 请求1请求了一个连接,用完后调用了close,此时JVM切换线程到请求2
(2) 请求2请求了一个连接,由于请求1已经用完了上一个连接,于是DBCP将请求1对应的connection给请求2使用。请求2还没开始使用,JVM切换线程回到请求1
(3) 在请求1的finally代码块中,又一次close了该connection,此时JVM调度线程回到请求2
(4) 请求2开始使用该connection,发生异常。
解决方法很简单,就是在正常代码中close connection之后随即将该connection设成null,然后在finally代码块中首先判断connection是否为null,不为null再close。加了这些判断之后,就避免了某个线程误close connection的现象发生。
以下是文档给出的示例代码:
CODE: SELECT ALL
1. Tomcat对DataSource类型的资源采用的是DBCP。DBCP支持JDBC 2.0, 在安装了JVM 1.4版本或更高的情况下,DBCP支持JDBC 3.0。
2. DBCP需要以下三个component,他们都来自Apache Jakarta Common Project,他们是:
Jakarta-Commons DBCP
Jakarta-Commons Collections
Jakarta-Commons Pool
这三个component都被包装在了$CATALINA_HOME/common/lib/naming-factory-dbcp.jar这个jar文件中。
3. Preventing DB Pool leaks. 这个很不错,DBCP为了防止应用程序忘记关闭ResultSets,Statements, Connections,特意设计了这样一个功能。DBCP能帮我们关闭不活动的connections,而且还能打印出stack trace,报告说是哪个class使用了connection,却没有关闭它。具体配置如下:
在定义DataSource的Resource定义中,加入attribute定义:
removeAbandoned="true"
这个属性默认配置为false。这样DBCP就可以关闭那些可能被应用程序忘记关闭的connection,具体的timeout设定这样配置:
removeAbandonedTimeout="60"
也就是说,如果DBCP发现一个connection 60秒内处于不活动状态,DBCP便自动回收。这个配置的默认值是300秒,也就是5分钟。
此外,还可以加入这个属性定义:
logAbandoned="true"
这样DBCP就会打印stack trace,让我们看到是哪个class忘记关闭connection。这个属性默认配置为false。
4. 文档给出了一个MySQL DataSource配置的例子。
(1) 将mysql jdbc的jar包放到$CATALINA_HOME/common/lib目录下。目前MySQL提供的官方驱动是Connector/J,目前EasyCluster中使用的是Connector/J 3.1.12版本,可以稳定工作。
(2) 在Tomcat中配置DataSource资源,以下例子给出的是在Context中的配置,也就说,只能给这个web app使用:
CODE: SELECT ALL
<Context path="/DBTest" docBase="DBTest" debug="5" reloadable="true" crossContext="true"> <!-- maxActive: 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. --> <!-- maxIdle: Maximum number of idle dB connections to retain in pool. Set to -1 for no limit. See also the DBCP documentation on this and the minEvictableIdleTimeMillis configuration parameter. --> <!-- maxWait: 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. --> <!-- username and password: MySQL dB username and password for dB connections --> <!-- driverClassName: Class name for the old mm.mysql JDBC driver is org.gjt.mm.mysql.Driver - we recommend using Connector/J though. Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver. --> <!-- url: 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. --> <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?autoReconnect=true"/> </Context>
(3) 配置web.xml
CODE: SELECT ALL
<resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/TestDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
(4) OK, 书写测试代码:
CODE: SELECT ALL
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <sql:query var="rs" dataSource="jdbc/TestDB"> select id, foo, bar from testdata </sql:query> <html> <head> <title>DB Test</title> </head> <body> <h2>Results</h2> <c:forEach var="row" items="${rs.rows}"> Foo ${row.foo}<br/> Bar ${row.bar}<br/> </c:forEach> </body> </html>
5. Common Problems I. 第一个常见问题就是“间歇性的取connection失败”。Tomcat分析说这是由于GC导致的。也就说,当GC发生的时候,Tomcat处于停止状态,如果GC花费的时间过长,长到超过了DBCP中配置的maxWait的时间,这种问题就会出现。DBCP中的maxWait表示的是当超过这个时间后,DBCP就认为取connection失败,这个值用毫秒表示。加入GC花费了15秒的时间(当然一般GC如果花费了10s就表示已经很恐怖了),而maxWait设定成10s的话,就会出现上面的问题了。解决方案是启动tomcat的时候加上-verbose:gc参数,观察每次gc花费的时间,然后微调maxWait或其他东西。
6. Common Problems II. Random Connection Close Exception. 这种问题EasyCluster中没有,他是这样产生的:
(1) 请求1请求了一个连接,用完后调用了close,此时JVM切换线程到请求2
(2) 请求2请求了一个连接,由于请求1已经用完了上一个连接,于是DBCP将请求1对应的connection给请求2使用。请求2还没开始使用,JVM切换线程回到请求1
(3) 在请求1的finally代码块中,又一次close了该connection,此时JVM调度线程回到请求2
(4) 请求2开始使用该connection,发生异常。
解决方法很简单,就是在正常代码中close connection之后随即将该connection设成null,然后在finally代码块中首先判断connection是否为null,不为null再close。加了这些判断之后,就避免了某个线程误close connection的现象发生。
以下是文档给出的示例代码:
CODE: SELECT ALL
Connection conn = null; Statement stmt = null; // Or PreparedStatement if needed ResultSet rs = null; try { conn = ... get connection from connection pool ... stmt = conn.createStatement("select ..."); rs = stmt.executeQuery(); ... iterate through the result set ... rs.close(); rs = null; stmt.close(); stmt = null; conn.close(); // Return to connection pool conn = null; // Make sure we don't close it twice } catch (SQLException e) { ... deal with errors ... } finally { // Always make sure result sets and statements are closed, // and the connection is returned to the pool if (rs != null) { try { rs.close(); } catch (SQLException e) { ; } rs = null; } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { ; } stmt = null; } if (conn != null) { try { conn.close(); } catch (SQLException e) { ; } conn = null; } }
相关文章推荐
- Tomcat 5.5.23 文档阅读Tips 7 - JNDI Resources
- Tomcat 5.5.23 文档阅读Tips 3 - Deployer
- Tomcat 5.5.23 文档阅读Tips 2 - Setup,有JSVC的重要内容
- Tomcat 5.5.23 文档阅读Tips 1 - Introduction
- Tomcat 5.5.23 文档阅读Tips 12 - APR and Tomcat
- Tomcat 5.5.23 文档阅读Tips 11 - Default Servlet
- Tomcat 5.5.23 文档阅读Tips 10 - SSL
- Tomcat 5.5.23 文档阅读Tips 9 - Class Loading
- Tomcat 5.5.23 文档阅读Tips 6 - Security Manager
- Tomcat 5.5.23 文档阅读Tips 5 - Realms and Access Control
- Tomcat 5.5.23 文档阅读Tips 4 - Manager
- 文档文件tomcat7.0怎样安装admin,进而配置Datasource
- Web项目开发环境中运行在Tomcat时涉及到JNDI的Datasource的解决方法
- Tomcat数据源(Tomcat DataSource JNDI Example )
- 在Tomcat上配置Proxool的DataSource(Jndi)
- JNDI Datasource HOW-TO(Tomcat 9)
- 在Tomcat上配置Proxool的DataSource(Jndi) --第2种方法
- Tomcat5.5中配置JNDI DataSource
- sql2005 jndi tomcat5.5.23 连接池
- JNDI初探之tomcat的datasource配置