2010-04-29 11 views
19

Tengo una aplicación de grails pequeña ejecutándose en Tomcat en Ubuntu en un VPS. Uso MySql como mi almacén de datos y todo funciona bien a menos que deje la aplicación por más de medio día (¿8 horas?). Realicé algunas búsquedas y aparentemente este es el predeterminado wait_timeout en mysql.cnf, así que después de 8 horas la conexión morirá pero Tomcat no lo sabrá, por lo tanto, cuando el siguiente usuario intente ver el sitio, verá el error de conexión fallida. Actualizar la página solucionará esto, pero quiero deshacerme por completo del error. Para mi versión de MySql (5.0.75) solo tengo my.cnf y no contiene dicho parámetro. En cualquier caso, cambiar este parámetro no resuelve el problema.Problema de tiempo de espera de conexión de MySQL - Aplicación Grails en Tomcat usando Hibernate y ORM

Parece que este Blog Post informa un error similar, pero aún no entiendo completamente qué debo configurar para solucionarlo y también espero que haya una solución más simple que otra biblioteca de terceros. La máquina en la que estoy corriendo tiene 256 MB de RAM y estoy tratando de mantener el número de programas/servicios funcionando al mínimo.

¿Hay algo que pueda configurar en Grails/Tomcat/MySql para que esto desaparezca?

Gracias de antemano,

Gav

Desde mi 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 

Respuesta

17

Refiriéndose a esta article, que tienen conexiones rancio en su piscina conexiones DBCP que se caen en silencio por el sistema operativo o cortafuegos.

La solución es definir una consulta de validación y hacer una verificación de la cordura de la conexión antes de usarla realmente en su aplicación. En este griales que realmente se hace modificando el/conf/archivo griales aplicación primavera/Resource.groovy y añadir lo siguiente:

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" 
    } 
} 
+0

es grails-app/conf/spring/Resource.grooy con grails-app/conf/spring/resources.groovy? Estoy usando Grails 1.2.1 y cuando lo agregué, me encontré con este error: === No se puede crear el controlador JDBC de la clase '' para conectar la URL 'nulo' java.sql.SQLException: Ningún controlador adecuado = == – firnnauriel

+0

de hecho, está funcionando si creé un nuevo Resource.groovy. está bien por ahora, supongo. – firnnauriel

+0

@firnnauriel ¿Esto realmente hizo lo que pretendía cuando creó el archivo Resource.groovy? – skaz

1

Intente aumentar el número de conexiones abiertas de MySQL, colocando lo siguiente en su DataSources.groovy:

dataSource { 
    driverClassName = "com.mysql.jdbc.Driver" 
    pooled=true 
    maxActive=10 
    initialSize=5 
    // Remaining connection params 
} 

Si quieres ir hasta el final, tratar de implementar un conjunto de conexiones; aquí hay un useful link sobre esto.

-1

¿Cómo se ve la cadena de conexión JDBC? Puede establecer un parámetro autoReconneect en la configuración de origen de datos, p.

jdbc:mysql://hostname/mydb?autoReconnect=true 
+0

no funciona para mí. Por lo que puedo decir, esto solo restablece la conexión después de que falla el intento, y todavía devuelve una excepción. – mcv

1

Por griales 1.3.x, he tenido que añadir el siguiente código a 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") 

    } 

también tuvo que importar org.codehaus.groovy.grails.commons.ApplicationAttributes

4

en griales 1.3.x, puede modificar los valores en el archivo de desalojador DataSource.groovy a hacer su las conexiones recompiladas se usan durante la inactividad. Esto asegurará que el servidor mysql no corte la conexión.

production { 
    dataSource { 
    pooled = true 
    // Other database parameters.. 
    properties { 
     maxActive = 50 
     maxIdle = 25 
     minIdle = 5 
     initialSize = 5 
     minEvictableIdleTimeMillis = 1800000 
     timeBetweenEvictionRunsMillis = 1800000 
     maxWait = 10000 
    } 
} 

Una forma rápida para verificar que esto funciona es modificar el fichero de configuración my.cnf MySQL [mysql] elemento y añadir parámetros wait_time con un valor bajo.

0

A partir de grails 2.3.6 configuración por defecto ya tiene opciones para prevenir el cierre de la conexión de tiempo de espera

Estos son los nuevos valores predeterminados.

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 
    } 
Cuestiones relacionadas