Apache Tomcat Servlet/JSP容器

Apache Tomcat 5.5 Servlet/JSP容器

Apache徽标

链接

用户指南

参考

Apache Tomcat开发

Apache Tomcat 5.5 Servlet/JSP容器

JNDI数据源HOW-TO

目录
介绍

JNDI数据源配置在JNDI-资源-HOWTO。然而,来自tomcat用户显示了单个配置的细节可能相当棘手。

下面是一些已发布到的示例配置tomcat用户的流行数据库和一些关于数据库使用的一般提示。

您应该知道,由于这些注释是从配置中派生出来的和/或反馈发布到tomcat用户基督教青年会:-)。请让我们知道你是否有任何其他测试过的配置,你觉得可能有用或者如果你觉得我们可以改进这一部分。

请注意,JNDI资源配置在Tomcat 5.0.x和Tomcat 5.5.x。您很可能需要修改JNDI按顺序匹配以下示例中的语法的资源配置使其在Tomcat 5.5.x中工作。

另外,请注意JNDI DataSource的一般配置特别是教程,假设您已经阅读并理解了上下文主机配置参考,包括后一参考中关于自动应用程序部署的部分。

数据库连接池(DBCP)配置

DBCP提供对JDBC 2.0的支持。在使用1.4 JVM DBCP的系统上将支持JDBC 3.0。请告知我们您是否使用了DBCP及其JDBC 3.0具有1.4 JVM。

请参阅DBCP文件以获取配置参数的完整列表。

安装

DBCP使用Jakarta-Commons数据库连接池。它依赖于雅加达常见组件的数量:

  • 雅加达-公共DBCP
  • 雅加达——常见收藏品
  • 雅加达公共游泳池
这些库位于单个JAR中$CATALINA_HOME/common/lib/naming-factory-dbcp.jar然而,只包括了连接池所需的类,并且包已被重命名,以避免干扰应用程序。

防止dB连接池泄漏

数据库连接池创建并管理连接池到数据库。回收和再利用现有连接到dB比打开新连接更有效。

连接池有一个问题。web应用程序具有显式关闭ResultSet、Statement和Connection。web应用程序关闭这些资源失败可能导致它们再也不能用于重用,这是一个数据库连接池“泄漏”。这最终可能导致web应用程序数据库连接失败如果没有更多可用的连接。

这个问题有一个解决方案。雅加达公共DBCP可以是配置为跟踪和恢复这些废弃的dB连接。不是它只能恢复它们,还可以生成代码的堆栈跟踪打开了这些资源,但从未关闭过。

要配置DBCP数据源,以便放弃的dB连接删除和回收后将以下属性添加到资源DBCP数据源的配置:

removeAbandoned=“true”
当可用的数据库连接运行时,低DBCP将恢复并回收找到任何废弃的dB连接。默认值为虚假的.

使用删除放弃超时属性设置数字秒,dB连接在被视为放弃之前已空闲。

removeAbandonedTimeout=“60”
删除放弃的连接的默认超时为300秒。

这个logAbandoned(日志已放弃)属性可以设置为真的如果希望DBCP记录放弃dB连接资源。

logAbandoned=“true”
默认值为虚假的.

MySQL DBCP示例

0.简介

的版本MySQL数据库和已报告工作的JDBC驱动程序:

  • MySQL 3.23.47,使用InnoDB的MySQL 3.23.47,MySQL 3.23.58,MySQL 4.0.1alpha
  • 连接器/J3.0.11-稳定(官方JDBC驱动程序)
  • mm.mysql(毫米)2.0.14(旧的第三方JDBC驱动程序)

在继续之前,不要忘记将JDBC驱动程序的jar复制到$CATALINA_HOME/common/lib.

1.MySQL配置

确保遵循这些说明,因为变化可能会导致问题。

创建一个新的测试用户、一个新数据库和一个测试表。您的MySQL用户必须指定密码。驾驶员如果您尝试使用空密码进行连接,将失败。

mysql>授予*.*上的所有特权javauser@localhost ->由“javadude”标识,带有授权选项;mysql>创建数据库javatest;mysql>使用javatest;mysql>创建表testdata(->id int不是null auto_increment主键,->foo varchar(25),->bar int);
注:一旦测试完成,应删除上述用户完成!

接下来,在testdata表中插入一些测试数据。

mysql>插入testdata值(null,'hello',12345);查询正常,1行受影响(0.00秒)mysql>select*from testdata;+----+-------+-------+|ID | FOO |酒吧|+----+-------+-------+|1|你好|12345|+----+-------+-------+一组1行(0.00秒)mysql>

2.上下文配置

通过为您的资源到您的上下文.

例如:

<上下文><!-- maxActive:池中dB连接的最大数量。确保你配置足够大的mysqld maxconnections来处理所有数据库连接。设置为-1表示无限制。--><!-- maxIdle:池中要保留的最大空闲dB连接数。设置为-1表示无限制。另请参阅DBCP文档和minEvictableIdleTimeMillis配置参数。--><!-- maxWait:等待dB连接可用的最长时间以毫秒为单位,在本例中为10秒。如果出现以下情况,将引发异常超过了这个超时时间。设置为-1表示无限期等待。--><!-- 用户名和密码:MySQL dB连接的用户名和密码--><!-- driverClassName:旧mm.mysql JDBC驱动程序的类名为org.gjt.mm.mysql网站。驱动程序-我们建议使用Connector/J。官方MySQL Connector/J驱动程序的类名是com.MySQL.jdbc。驾驶员。--><!-- url:用于连接到MySQL dB的JDBC连接url。--><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"/></上下文>

3.web.xml配置

现在创建一个WEB-INF/WEB.xml用于此测试应用程序。

<web-app xmlns=“http://java.sun.com/xml/ns/j2ee"xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=“http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"版本=“2.4”>MySQL测试应用程序<资源-资源><description>数据库连接<res ref name>jdbc/TestDB</res ref name><res-type>javax.sql。数据源</res-type><res auth>容器</res auth></resource-ref></web-app>

4.测试代码

现在创建一个简单的测试.jsp页面供以后使用。

<%@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”>从testdata中选择id、foo、bar</sql:query><html><头部>数据库测试</头><body><h2>结果</h2><c:forEach var=“row”items=“${rs.rows}”>Foo${row.Foo}<br/>条形图${row.Bar}<br/></c:forEach></body></html>

该JSP页面使用JSTL公司的SQL和Core标记库。你可以从Sun那里买到Java Web Services开发包雅加达Taglib标准1.1项目-只需确保获得1.1.x版本。一旦你有了JSTL,复制jstl.jar文件标准.jar到您的web应用程序WEB-INF/库目录。

最后将您的web应用程序部署到$CATALINA_HOME/webapps任何一个作为一个名为数据库测试.war或进入名为数据库测试

部署后,将浏览器指向http://localhost:8080/DBTest/test.jsp查看你的努力工作。

Oracle 8i、9i和10g

0.简介

除了常见问题:-)

旧Oracle版本的驱动程序可能以*.zip文件的形式分发,而不是而不是*.jar文件。Tomcat将仅使用*.jar文件文件安装在$CATALINA_HOME/common/lib.因此类111.zip类12.zip将需要重命名为.jar文件扩展。因为jarfiles是zipfiles,所以不需要解压缩和jar文件&简单的重命名就足够了。

对于Oracle 9i以后的版本,您应该使用oracle.jdbc。Oracle驱动程序而不是oracle.jdbc.driver。Oracle驱动程序正如Oracle所说那个oracle.jdbc.driver。Oracle驱动程序已弃用并支持对于此驱动程序类,将在下一个主要版本中停止使用。

1.上下文配置

与上面的mysql配置类似,您需要定义您的上下文。这里我们定义了一个名为myoracle的数据源使用瘦驱动程序作为用户scott进行连接,将老虎密码输入名为mysid的sid。(注意:对于瘦驱动程序,此sid是与tnsname不同)。所使用的架构将是用户scott。

使用OCI驱动程序只需在URL字符串中将thin更改为OCI。

<资源name=“jdbc/myoracle”auth=“容器”type=“javax.sql.DataSource”driverClassName=“oracle.jdbc.OracleDriver”url=“jdbc:oracle:thin:@127.0.0.1:1521:mysid”username=“scott”password=“tiger”maxActive=“20”maxIdle=“10”maxWait=“-1”/>

2.web.xml配置

当您执行以下操作时,应该确保遵守DTD定义的元素顺序创建应用程序web.xml文件。

<资源-资源><description>Oracle数据源示例<res-ref-name>jdbc/myoracle<res-type>javax.sql。数据源</res-type>容器</resource-ref>

3.代码示例

您可以使用与上面相同的示例应用程序(在创建所需的数据库时实例、表等)将数据源代码替换为以下内容

Context initContext=new InitialContext();Context envContext=(Context)initContext.lookup(“java:/comp/env”);DataSource ds=(DataSource)envContext.lookup(“jdbc/myoracle”);连接conn=ds.getConnection();//等。
PostgreSQL

0.简介

PostgreSQL的配置方式与Oracle类似。

1.所需文件

将Postgres JDBC jar复制到$CATALINA_HOME/common/lib。与Oracle一样为了让DBCP的Classloader能够找到他们。无论您下一步执行哪个配置步骤,都必须执行此操作。

2.资源配置

这里有两个选择:定义一个跨所有Tomcat共享的数据源应用程序,或者专门为一个应用程序定义数据源。

2a、。共享资源配置

如果要定义跨多个Tomcat应用程序,或者如果您只想定义数据源在此文件中。

这位作者在这里没有取得成功,尽管其他人也有报道。请在此澄清。

<资源name=“jdbc/postgres”auth=“容器”type=“javax.sql.DataSource”driverClassName=“org.postgresql.Driver”url=“jdbc:postgresql://127.0.0.1:5432/mydb"username=“myuser”password=“mypasswd”maxActive=“20”maxIdle=“10”maxWait=“-1”/>

2b、。特定于应用程序的资源配置

如果要定义特定于应用程序的数据源,请使用此选项,其他Tomcat应用程序不可见。这种方法对您的Tomcat安装。

为您的上下文.Context元素应该如下所示。

<上下文><资源name=“jdbc/postgres”auth=“容器”type=“javax.sql.DataSource”driverClassName=“org.postgresql.Driver”url=“jdbc:postgresql://127.0.0.1:5432/我的数据库"username=“myuser”password=“mypasswd”maxActive=“20”maxIdle=“10”maxWait=“-1”/></上下文>

3.web.xml配置

<资源-资源>postgreSQL数据源示例<res-ref-name>jdbc/postgres</res-ref_name><res-type>javax.sql。数据源</res-type>容器</resource-ref>

4.访问数据源

以编程方式访问数据源时,请记住预先发送java:/comp/env语言到您的JNDI查找,如下面的片段代码。还请注意,“jdbc/postgres”可以替换为您喜欢的任何值,前提是您也可以在上面的资源定义文件中更改它。

InitialContext cxt=新的InitialContext();if(cxt==空){抛出新的异常(“噢,没有上下文!”);}数据源ds=(DataSource)cxt.lookup(“java:/comp/env/jdbc/postgres”);if(ds==空){throw new Exception(“找不到数据源!”);}
非DBCP解决方案

这些解决方案要么使用到数据库的单一连接(不建议用于其他任何情况比测试更重要!)或其他一些池技术。

带OCI客户端的Oracle 8i
介绍

虽然没有严格解决使用OCI客户端创建JNDI数据源的问题,但这些注释可以与上述Oracle和DBCP解决方案。

为了使用OCI驱动程序,您应该安装Oracle客户端。你应该已经安装了从cd下载Oracle8i(8.1.7)客户端,并下载合适的JDBC/OCI驱动程序(Oracle8i 8.1.7.1 JDBC/OCI驱动程序)otn.oracle.com网站.

重命名后类12.zip文件到类12.jar对于Tomcat,将其复制到$CATALINA_HOME/common/lib. 您可能还必须删除javax.sql*根据您使用的Tomcat和JDK的版本,从该文件中删除。

把它们放在一起

确保您拥有ocijdbc8.dll.所以在您的$路径LD_LIBRARY_PATH(本地_远程_路径)(可能在$ORAHOME\bin(ORAHOME))并确认本地库可以通过简单的测试程序加载使用System.loadLibrary(“ocijdbc8”);

接下来,您应该创建一个简单的测试servlet或jsp,其中包含以下内容关键线路:

DriverManager.registerDriver(新oracle.jdbc.driver。OracleDriver());康纳=DriverManager.getConnection(“jdbc:oracle:oci8:@database”,“用户名”,“密码”);

其中数据库的形式主机:端口:SID现在,如果您尝试访问您的测试servlet/jsp,得到的是Servlet异常根本原因是java.lang.UnsatisfiedLink错误:get_env_handle.

首先未满足的链接错误表示您已经

  • JDBC类文件和您的Oracle客户端版本。这里泄露的信息是,所需的库文件不能找到。例如,您可能正在使用来自Oracle 8.1.6版和8.1.5版的classes12.zip文件Oracle客户端。classeXXXs.zip文件和Oracle客户端软件版本必须匹配。
  • A类$路径,LD_LIBRARY_PATH(本地_远程_路径)问题。
  • 据报道,忽略从otn下载的驱动程序并使用目录中的classes12.zip文件$ORAHOME\jdbc\lib也会起作用。

接下来您可能会遇到错误ORA-06401 NETCMN:无效的驱动程序指示符

Oracle文档说明:“原因:登录(连接)字符串包含无效的驾驶员指示器。操作:更正字符串并重新提交。"更改(表单的)数据库连接字符串主机:端口:SID)用这个:(描述=(地址=(主机=我的主机)(协议=tcp)(端口=1521))(连接数据=(sid=orcl))

Ed.嗯,我认为如果你整理你的TNSNames,这不是真的需要的-但我不是Oracle DBA:-)

常见问题

以下是web应用程序遇到的一些常见问题使用数据库和解决方法的提示。

间歇性dB连接故障

Tomcat在JVM中运行。JVM定期执行垃圾收集(GC)删除不再使用的java对象。当JVM在Tomcat冻结中执行代码的GC执行。如果最大时间配置用于建立dB连接的数量小于垃圾收集花费的时间可能会导致数据库连接失败。

要收集有关垃圾收集所需时间的数据,请添加-详细:gc与您的CATALINA_OPTS目录启动Tomcat时的环境变量。启用详细gc时你的$CATALINA_BASE/logs/CATALINA.out日志文件将包括每个垃圾收集的数据,包括所用的时间。

当您的JVM被正确调优99%的时间时,GC将花费更少的时间超过一秒钟。剩下的只需几秒钟。很少,如果有,GC应该花费10秒以上。

确保数据库连接超时设置为10-15秒。对于DBCP,可以使用参数设置最大等待时间.

随机连接关闭异常

当一个请求从连接中获取数据库连接时,可能会出现这些情况游泳池并将其关闭两次。使用连接池时,请关闭connection只需将其返回池以供另一个请求重用,它不会关闭连接。Tomcat使用多个线程处理并发请求。下面是一个序列示例可能在Tomcat中导致此错误的事件数:

在线程1中运行的请求1获得一个数据库连接。请求1关闭数据库连接。JVM将正在运行的线程切换到线程2线程2中运行的请求2获得数据库连接(请求1刚刚关闭了相同的数据库连接)。JVM将正在运行的线程切换回线程1请求1在finally块中第二次关闭数据库连接。JVM将正在运行的线程切换回线程2请求2线程2尝试使用数据库连接,但失败因为请求1关闭了它。
下面是一个使用db连接的正确编写的代码示例从连接池中获取:
连接conn=null;语句语句=null;//或PreparedStatement(如果需要)结果集rs=null;尝试{conn=。。。从连接池获取连接。。。stmt=conn.createStatement(“选择…”);rs=stmt.executeQuery();…遍历结果集。。。rs.close();rs=空;语句关闭();stmt=空;连接关闭();//返回连接池conn=空;//确保我们不会关闭它两次}catch(SQLException e){…处理错误。。。}最后{//始终确保结果集和语句已关闭,//并将连接返回到池if(rs!=空){尝试{rs.close();}catch(SQLException e){;}rs=空;}if(语句!=空){尝试{stmt.close();}catch(SQLException e){;}stmt=空;}if(conn!=空){尝试{conn.close();}捕获(SQLException e){;}conn=空;}}

上下文与GlobalNamingResources

请注意,尽管上述说明将JNDI声明放在Context中元素中,可以将这些声明放置在全局命名资源服务器的部分配置文件。将共享GlobalNamingResources部分中的资源在服务器的上下文中。

JNDI资源命名与领域交互

为了让Realms工作,领域必须将数据源引用为在<GlobalNamingResources>或<Context>部分中定义,而不是重命名的数据源使用<ResourceLink>。


版权所有©1999-2012,Apache Software Foundation