使用 DBCP 配置 Tomcat
Posted
技术标签:
【中文标题】使用 DBCP 配置 Tomcat【英文标题】:Tomcat Configuration using DBCP 【发布时间】:2011-06-24 10:30:27 【问题描述】:经过一段时间(几个小时)后,我们收到了 CommunicationsException(来自 DBCP)。错误消息(在异常中)在这个问题的末尾 - 但我没有看到任何配置文件中定义的 wait_timeout 。 (我们应该看哪里?tomcat/conf 目录之外的某个地方?)。
其次,正如异常所建议的那样,将“Connector/J 连接属性 'autoReconnect=true'”放在哪里?下面是tomcat设置文件conf/context.xml中的资源定义:
<Resource name="jdbc/TomcatResourceName" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
username="xxxx" password="yyyy"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/dbname?autoReconnect=true"/>
第三,为什么JVM要等到调用executeQuery()才抛出异常?如果连接超时,getConnection 方法应该抛出异常,不是吗?这是我正在谈论的源代码部分:
try
conn = getConnection (true);
stmt = conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rset = stmt.executeQuery (bQuery);
while (rset.next())
....
最后,这是堆栈跟踪的第一几行...
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 84,160,724 milliseconds ago. The last packet sent successfully to the server was 84,160,848 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3291)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1938)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2107)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2642)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2571)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1451)
at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
这就是我们中的一些人认为“忘记 dbcp,它可能非常依赖于 IDE 配置和幕后魔术,以至于 DriverManager.getConnection(...) 可能更可靠”的原因。有cmet吗?感谢您的见解,-MS
【问题讨论】:
【参考方案1】:由于 DBCP 为即将到来的连接请求保持打开返回的 mysql 连接,它们成为MySQL Server timeout 的受害者。
DBCP 有许多可以提供帮助的功能(可以从 Tomcat 5.5 IIRC 开始使用)。
validationQuery="SELECT 1"
testOnBorrow="true"
验证确保连接有效,然后再将其返回到执行“借用”方法的 web 应用程序。标志当然会启用此功能。
如果超时(我相信是 8 小时)过去并且连接已失效,则测试一个新连接(如果不再存在,则创建它)并将其提供给 webapp。
其他可能的方法:
在您的资源设置中使用testWhileIdle="true"
DBCP 也可以在检测到有效请求之前检查空闲连接。
使用“connectionProperties”加强您的 MySQL 连接(例如 autoReconnect/autoReconnectForPools=true
)
【讨论】:
如果我理解正确,DBCP 将其连接保留在其池中,但 mySql 服务器超时,因此当此连接发送到应用程序时,它是一个关闭连接。有道理,但这是我的正确理解吗?另一个问题:在 context.xml 文件中使用您提到的 validationQuery/testOnBorrow 以及 testWhileIdle 和 autoRecon... 有什么意义吗?他们进入那个文件,对吧? 1.你的理解是正确的。我指出的所有解决方案都是互补的。设置一个,并不妨碍设置其他。腰带和背带更好;-) 我会实施所有 3 种解决方案。空闲时进行测试意味着“借用”时间的等待时间更少。属性设置将减少不合时宜的断开连接。是的,它们都进入你的 webapp 的 context.xml 的资源部分(后来由 tomcat 部署在 $CATALINA_HOME/conf/Catalina/localhost/yourwebapp.xml 中)。 不推荐自动重新连接 - dev.mysql.com/doc/refman/5.0/en/…【参考方案2】:DBCP 不适合在生产环境中使用,甚至作者都这么说(请参阅此演示文稿:http://www.infoq.com/presentations/Tuning-Tomcat-Mark-Thomas)。
我建议看看C3P0:http://www.mchange.com/projects/c3p0/index.html
【讨论】:
这不是那么真实。关于您的比较有一些线索,差异不明显或不明确。 ***.com/questions/520585/… 和 ***.com/questions/490288/… 该演示文稿讨论了何时使用 BIO 和 NIO,具体取决于会话长度和并发要求(我们在这两个问题上都处于低水平)。关于为什么不应该在生产中使用它的任何指针?只是高频率的连接考虑?顺便说一句,我确实看过 C3P0,看起来很有趣,如果 DBCP 一直给我们带来问题,我们可能会尝试一下。谢谢你的信息,-MS。 如果我没记错的话,这个演示文稿中有一个要点,当那个人说“DBCP 从来没有用于生产”或类似的东西时。是的,这是大海捞针,但我听了之后就无法忘记。 C3P0 不支持 JDBC4 功能。来源:sourceforge.net/tracker/…以上是关于使用 DBCP 配置 Tomcat的主要内容,如果未能解决你的问题,请参考以下文章