MySQL连接超时问题 - 在Tomcat上使用休眠和ORM的Grails应用程序
我在VPS上的Ubuntu上的Tomcat上运行了一个小型的grails应用程序。我使用MySql作为我的数据存储,一切工作正常,除非我离开应用半天以上(8小时?)。我做了一些搜索,显然这是mysql.cnf中的默认wait_timeout
,所以在8小时后,连接将会终止,但当下一个用户尝试查看站点时,Tomcat不会知道,他们将看到连接失败错误。刷新页面将解决这个问题,但我想完全摆脱错误。对于我的MySql版本(5.0.75),我只有my.cnf,并且它不包含这样的参数,在任何情况下,更改此参数都不能解决问题。MySQL连接超时问题 - 在Tomcat上使用休眠和ORM的Grails应用程序
这个Blog Post似乎报告了一个类似的错误,但我仍然不完全理解我需要配置得到这个固定的,我希望有一个比另一个第三方库更简单的解决方案。我正在运行的机器有256MB内存,我正在努力将运行的程序/服务数量降到最低。
有没有什么我可以在Grails/Tomcat/MySql中配置让它消失?
由于提前,
GAV株系
从我的catalina.out的;
2010-04-29 21:26:25,946 [http-8080-2] ERROR util.JDBCExceptionReporter - The last packet successfully received from the server was 102,906,722 milliseconds$
2010-04-29 21:26:25,994 [http-8080-2] ERROR errors.GrailsExceptionResolver - Broken pipe
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
...
2010-04-29 21:26:26,016 [http-8080-2] ERROR util.JDBCExceptionReporter - Already closed.
2010-04-29 21:26:26,016 [http-8080-2] ERROR util.JDBCExceptionReporter - Already closed.
2010-04-29 21:26:26,017 [http-8080-2] ERROR servlet.GrailsDispatcherServlet - HandlerInterceptor.afterCompletion threw exception
org.hibernate.exception.GenericJDBCException: Cannot release connection
at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:84)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:181)
... 1 more
参考此article,您的DBCP连接池中已陈旧的连接被操作系统或防火墙无提丢弃。
解决方案是定义一个验证查询,并在实际在应用程序中使用它之前对连接进行完整性检查。 Grails中这实际上是通过修改的grails-app/conf目录/春/ Resource.groovy文件,并添加做了以下:
beans = {
dataSource(BasicDataSource) {
//run the evictor every 30 minutes and evict any connections older than 30 minutes.
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
//test the connection while its idle, before borrow and return it
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
尝试通过把你的DataSources.groovy以下提高开放的MySQL连接数:
dataSource {
driverClassName = "com.mysql.jdbc.Driver"
pooled=true
maxActive=10
initialSize=5
// Remaining connection params
}
如果要干到底,尽量实现一个连接池;这里是一个useful link。
你的JDBC连接字符串是什么样的?您可以在数据源配置中设置一个autoReconneect
参数,例如
jdbc:mysql://hostname/mydb?autoReconnect=true
不为我工作。据我所知,这只会在尝试失败后重新建立连接,并且它仍会返回一个异常。 – mcv 2011-01-18 09:47:19
Grails的1.3.X,我不得不将以下代码添加到BootStrap.groovy中:
def init = {servletContext ->
def ctx=servletContext.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT)
//implement test on borrow
def dataSource = ctx.dataSource
dataSource.targetDataSource.setMinEvictableIdleTimeMillis(1000 * 60 * 30)
dataSource.targetDataSource.setTimeBetweenEvictionRunsMillis(1000 * 60 * 30)
dataSource.targetDataSource.setNumTestsPerEvictionRun(3)
dataSource.targetDataSource.setTestOnBorrow(true)
dataSource.targetDataSource.setTestWhileIdle(true)
dataSource.targetDataSource.setTestOnReturn(false)
dataSource.targetDataSource.setValidationQuery("SELECT 1")
}
我也不得不进口org.codehaus.groovy.grails.commons.ApplicationAttributes
Grails中1.3.X,你可以修改DataSource.groovy文件中逐出值让苏在空闲期间使用重新连接的连接。这将确保mysql服务器不会超时连接。
production {
dataSource {
pooled = true
// Other database parameters..
properties {
maxActive = 50
maxIdle = 25
minIdle = 5
initialSize = 5
minEvictableIdleTimeMillis = 1800000
timeBetweenEvictionRunsMillis = 1800000
maxWait = 10000
}
}
一个快速的方法来验证这个作品是修改的MySQL my.cnf配置文件[MySQL的]元素和具有低值添加WAIT_TIME参数。
从grails 2.3.6默认配置开始已经为防止因超时而
关闭连接这些都是新的默认选项。
properties {
// See http://grails.org/doc/latest/guide/conf.html#dataSource for documentation
....
minIdle = 5
maxIdle = 25
maxWait = 10000
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
validationQuery = "SELECT 1"
validationQueryTimeout = 3
validationInterval = 15000
testOnBorrow = true
testWhileIdle = true
testOnReturn = false
jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}
这些参数添加到数据源
testOnBorrow = true
testWhileIdle = true
testOnReturn = true
请参阅本文的详细信息 http://sacharya.com/grails-dbcp-stale-connections/
是否与grails-app/conf/spring/resources.groovy一样是grails-app/conf/spring/Resource.grooy?我使用grails 1.2.1,当我添加它时,我遇到了这个错误: === 无法为连接URL创建类''的JDBC驱动程序'null' java.sql.SQLException:没有合适的驱动程序 = == – firnnauriel 2010-07-22 09:03:58
的确,它正在工作,如果我创建了一个新的Resource.groovy。这很好,现在我猜。 – firnnauriel 2010-07-22 09:12:53
@firnnauriel当你创建Resource.groovy文件时,这实际上做了你想要的吗? – skaz 2011-08-31 19:46:17