在MySQL,Grails 2应用程序更长时间不活动期间保持池连接活动(或将它们计时并获得新的连接)的正确方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在MySQL,Grails 2应用程序更长时间不活动期间保持池连接活动(或将它们计时并获得新的连接)的正确方法相关的知识,希望对你有一定的参考价值。
我有一个grails应用程序,有高活动的flurries,但往往是一段时间不活动,可以持续几个小时到一个晚上。我注意到早上的第一批用户得到以下类型的异常,我相信这是由于池中的连接过时而mysql数据库关闭它们。
我在Googling中发现有关使用Connector / J连接属性'autoReconnect = true'是否是一个好主意的信息(以及即使连接被恢复,客户端是否仍然会获得异常),或者是否设置其他属性将周期性地逐出或刷新空闲连接,测试借用等.Grails使用下面的DBCP。我目前有一个简单的配置,如下所示,我正在寻找一个答案,如何最好地确保在长时间非活动期间有效且未关闭后从池中抓取任何连接。
dataSource {
pooled = true
dbCreate = "update"
url = "jdbc:mysql://my.ip.address:3306/databasename"
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = "****"
password = "****"
properties {
//what should I add here?
}
}
例外
2012-06-20 08:40:55,150 [http-bio-8443-exec-1] ERROR transaction.JDBCTransaction - JDBC begin failed
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 64,129,968 milliseconds ago. The last packet sent successfully to the server was 64,129,968 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 com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3851)
...... Lots more .......
Caused by: java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:114)
最简单的方法是配置连接池以指定在将连接传递给应用程序之前运行的查询以测试连接:
validationQuery="select 1 as dbcp_connection_test"
testOnBorrow=true
可以在其他事件上运行相同的“连接验证”查询。我不确定这些的默认值:
testOnReturn=true
testWhileIdle=true
还有一些配置设置可以限制池中空闲连接的“年龄”,如果在服务器端关闭空闲连接,这可能很有用。
minEvictableIdleTimeMillis
timeBetweenEvictionRunsMillis
http://commons.apache.org/dbcp/configuration.html
我不知道它是否是处理数据库连接的最佳方式,但我遇到了与您描述的问题相同的问题。我尝试了很多,最后得到了c3p0 connection pool。
使用c3p0可以强制您的应用在一段时间后刷新数据库连接。
将c3p0.jar
放入lib
文件夹,并将配置添加到conf/spring/resources.groovy
。
我的resources.groovy
看起来像这样:
import com.mchange.v2.c3p0.ComboPooledDataSource
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
beans = {
/**
* c3P0 pooled data source that forces renewal of DB connections of certain age
* to prevent stale/closed DB connections and evicts excess idle connections
* Still using the JDBC configuration settings from DataSource.groovy
* to have easy environment specific setup available
*/
dataSource(ComboPooledDataSource) { bean ->
bean.destroyMethod = 'close'
//use grails' datasource configuration for connection user, password, driver and JDBC url
user = CH.config.dataSource.username
password = CH.config.dataSource.password
driverClass = CH.config.dataSource.driverClassName
jdbcUrl = CH.config.dataSource.url
//force connections to renew after 4 hours
maxConnectionAge = 4 * 60 * 60
//get rid too many of idle connections after 30 minutes
maxIdleTimeExcessConnections = 30 * 60
}
}
以上是关于在MySQL,Grails 2应用程序更长时间不活动期间保持池连接活动(或将它们计时并获得新的连接)的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot连接MySQL长时间不连接后报错`com.mysql.cj.core.exceptions.ConnectionIsClosedException: No operations
在 Grails 应用程序中为长时间运行的作业构建队列的最佳方法是啥?