java 使用 DBCP 的 Tomcat 配置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4950396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Tomcat Configuration using DBCP
提问by Manidip Sengupta
We are getting a CommunicationsException (from DBCP) after iding for a while (a few hours). The error message (in the Exception) is at the end of this question - but I dont see wait_timeout defined in any of the configuration files. (Where should we look? Somewhere out of the tomcat/conf directory?).
经过一段时间(几个小时)后,我们收到了 CommunicationsException(来自 DBCP)。错误消息(在异常中)在这个问题的末尾 - 但我没有看到任何配置文件中定义的 wait_timeout 。(我们应该在哪里看?在 tomcat/conf 目录之外的某个地方?)。
Secondly, as suggested by the Exception, where does one put the "Connector/J connection property 'autoReconnect=true'"? Here is the resource definition in the file conf/context.xml in tomcat set up:
其次,正如异常所建议的那样,将“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"/>
Thirdly, why does the JVM wait till the call to executeQuery() to throw the Exception? If the connection has timed out, the getConnection method should throw the Exception, shouldn't it? This is the section of the source code I am talking about:
第三,为什么 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()) {
....
Finally, here are the 1st few lines of the Stack trace...
最后,这是堆栈跟踪的第一行...
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)
These are the reasons some of us are thinking "forget dbcp, it may be so dependent on IDE configurations and under-the-hood magic that DriverManager.getConnection(...) may be more reliable". Any comments on that? Thank you for your insights, - MS
这些是我们中的一些人认为“忘记 dbcp,它可能如此依赖于 IDE 配置和幕后魔法,DriverManager.getConnection(...) 可能更可靠”的原因。对此有何评论?谢谢你的见解, - MS
回答by Alain Pannetier
Since DBCP keeps returned mysql connections open for upcoming connection requests, they fall victims to the MySQL Server timeout.
由于 DBCP 为即将到来的连接请求保持返回的 mysql 连接打开,因此它们成为MySQL 服务器超时的受害者。
DBCP has a number of features that can help (can be used starting with Tomcat 5.5 IIRC).
DBCP 有许多可以提供帮助的功能(可以从 Tomcat 5.5 IIRC 开始使用)。
validationQuery="SELECT 1"
testOnBorrow="true"
The validation makes sure that a connection is valid before returning it to a webapp executing the 'borrow' method. The flag of course, enables this feature.
在将连接返回到执行“借用”方法的 web 应用程序之前,验证确保连接有效。当然,该标志启用了此功能。
If the timeout (8 hours I believe) is elapsed and the connection is dead, then a new connection is tested (if there are none anymore, it is created) and provided to the webapp.
如果超时(我相信 8 小时)已过并且连接已失效,则测试新连接(如果不再有,则创建)并提供给 webapp。
Other possible approaches:
其他可能的方法:
use the
testWhileIdle="true"
DBCP in your resource settings to also check idle connections before an effective request is detected.Use the 'connectionProperties' to harden your MySQL connection (e.g.
autoReconnect/autoReconnectForPools=true
)
testWhileIdle="true"
在检测到有效请求之前,还可以在资源设置中使用DBCP 来检查空闲连接。使用“connectionProperties”来强化您的 MySQL 连接(例如
autoReconnect/autoReconnectForPools=true
)
回答by Spajus
DBCP is not meant for use in production, even the authors say that (see this presentation: http://www.infoq.com/presentations/Tuning-Tomcat-Mark-Thomas).
DBCP 不打算用于生产,即使作者也这么说(请参阅此演示文稿:http: //www.infoq.com/presentations/Tuning-Tomcat-Mark-Thomas)。
I suggest taking a look at C3P0: http://www.mchange.com/projects/c3p0/index.html
我建议看看 C3P0:http: //www.mchange.com/projects/c3p0/index.html