2012-07-31 12 views
5

Tenemos una API que utiliza hibernación como herramienta ORM y usamos c3p0 como el controlador de grupo de conexiones. No tenemos problemas cuando estamos bajo carga. Sin embargo, nos estamos quedando sin excepciones de "incapaz de obtener una conexión" cuando la API ha estado inactiva por un día más o menos. Entonces, si ningún cuerpo usa la API durante el fin de semana, recibimos errores de conexión el lunes por la mañana.Tiempo de espera de conexión después del período de inactividad

Caused by: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out. 

Utilizamos mysql como base de datos. En mi investigación, llegué a saber que mySQL hace que las conexiones se vuelvan obsoletas después de 8 horas más o menos. Es posible que el grupo de conexiones proporcione una conexión obsoleta al cliente y, por lo tanto, las excepciones de tiempo de espera de conexión para el cliente.

En este momento, no tenemos ninguna prueba de conexión configurada en C3Po. Digamos, si uso IdleTestPeriod para probar la conexión antes de que el grupo la dé al cliente. Entonces, ¿qué sucede si todas mis conexiones no pasan la prueba en un momento determinado? ¿Se eliminarán esas conexiones fallidas del grupo y se generarán nuevas conexiones activas de nuevo?

Actualmente, esta es la configuración de c3p0 que estamos utilizando. ¿Alguna otra razón posible para este problema?

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
     <property name="driverClass" value="${----}"/> 
     <property name="jdbcUrl" value="${----}"/> 
     <property name="user" value="${----}"/> 
     <property name="password" value="${------}"/> 
     <property name="minPoolSize" value="5"/> 
     <property name="acquireIncrement" value="5" /> 
     <property name="maxPoolSize" value="125" /> 
     <property name="maxStatements" value="10" /> 
     <property name="maxIdleTime" value="180" /> 
     <property name="maxIdleTimeExcessConnections" value="30" /> 
     <property name="checkoutTimeout" value="3000" /> 
     <property name="preferredTestQuery" value="SELECT 1" /> 
    </bean> 

Gracias por la ayuda

Respuesta

1

En la sección de alta disponibilidad y clustering en MySQL Java Connector, echar un vistazo a las propiedades; específicamente autoReconnect y autoReconnetForPools. Usa las propiedades en tu URL de conexión JDBC. Me han ayudado antes al utilizar MySQL, Hibernate y C3P0. Espero que esto ayude

9

Así que tiene un checkoutTimeout de 3 segundos (3000 msecs) establecido. Esa es la Excepción que estás viendo. Los clientes solo pueden esperar tres segundos para pagar una Conexión desde el grupo; si tres segundos no son suficientes, ven su Excepción.

La pregunta es, ¿por qué los clientes tardan tanto en obtener una conexión? Normalmente, verificar una conexión es una operación bastante rápida. Pero si todas las conexiones están desprotegidas, los clientes tendrán que esperar (lentamente) la adquisición de la conexión desde la base de datos.

Tiene configurada su agrupación para eliminar de forma agresiva las conexiones. Cualquier cantidad de conexiones superiores a minPoolSize = 5 se destruirá si permanecen inactivas durante más de maxIdleTimeExcessConnections = 30 segundos. Sin embargo, su grupo está configurado para ráfagas a gran escala: maxPoolSize = 125. Supongamos que su aplicación está en silencio por un tiempo, y luego recibe una ráfaga de solicitudes de conexión de los clientes. El conjunto se agotará rápidamente de Connections y comenzará a adquirir, en ráfagas de acquireIncrement = 5. Pero si de repente hay 25 clientes y el grupo tiene solo 5 conexiones, no es improbable que el cliente número 25 agote el tiempo de espera antes de adquirir una conexión.

Hay muchas cosas que puedes hacer. Estos ajustes son separables, puede mezclar o combinar como mejor le parezca.

1) Ralentí inactivo "exceso" Se conecta de forma menos agresiva, por lo que, en general, su grupo tiene cierta capacidad para atender ráfagas de solicitudes. Puede descartar maxIdleTimeExcessConnections por completo y dejar que Connections vaya lentamente después de maxIdleTime = 180 segundos de desuso. (Desventaja: una huella de recursos más grande durante más tiempo durante los períodos de inactividad)

2) Establezca minPoolSize en un valor superior, de modo que es poco probable que el grupo muestre un estallido de actividad para el que tiene muy pocas conexiones (Desventaja ? Huella de recursos permanente más grande.)

3) Drop checkTimeout de su configuración. El valor predeterminado de c3p0 es permitir a los clientes esperar indefinidamente para una conexión. (A la baja quizás prefiera que los clientes informen rápidamente un error en lugar de esperar un posible éxito)

No creo que el problema que está observando tenga mucho que ver con las pruebas de conexión o los tiempos de espera de MySQL per se, pero eso no significa que no deba lidiar con esos problemas. Me inclinaré por el consejo de nobeh sobre el problema de reconexión de MySQL. (No soy un gran usuario de MySQL). Debería considerar implementar pruebas de conexión. Tiene un TestQuery preferido, por lo que las pruebas deben ser razonablemente rápidas. Mi elección habitual es usar testConnectionOnCheckin y idleConnectionTestPeriod. Ver http://www.mchange.com/projects/c3p0/#configuring_connection_testing

¡Buena suerte!

Cuestiones relacionadas