es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo recuperarse de conexiones abandonadas?

Tenía consultas largas en producción debido a las cuales las conexiones se cerraban/abandonaban. Como resultado, actualicé removeAbandonedTimeout a 1800 segundos. Después de esto, el 95% del problema desapareció. Pero de manera muy aleatoria, una o dos veces al mes todavía obtengo errores de conexión abandonada.

El problema aquí es que volver a intentar después de esperar durante 15 segundos después de capturar esta excepción no ayuda a resolver el problema. Las consultas subsecuentes fallan inmediatamente con una excepción de conexión abandonada.

Mi configuración actual del pool:

maxActive=50;
maxIdle=1;
minIdle=0;
initialSize=0;
maxWait=10000;
testOnBorrow=true;
testOnReturn=false;
timeBetweenEvictionRunsMillis=5000;
minEvictableIdleTimeMillis=2000;
testWhileIdle=false;
testOnConnect=false;
validationQuery=SELECT 1;
validationQueryTimeout=-1;
validationInterval=30000;
removeAbandoned=true;
removeAbandonedTimeout=1800;
logAbandoned=true;
jdbcInterceptors=ConnectionState;StatementFinalizer;ResetAbandonedTimer;

Replicación

Base de datos utilizada: PostgreSQL

Cambié removeAbandonedTimeout a 30seg . El primer pg_sleep falló ya que excedió el tiempo de espera y entró en el bloque catch. Mi expectativa era que, dado que la conexión es eliminada por el abandonedTimer en segundo plano, el siguiente pg_sleep(10) debería solicitar una nueva conexión y debería ejecutarse correctamente ya que testOnBorrow es true. Así que intenté dormir el hilo actual durante 30 segundos y ejecuté el siguiente pg_sleep. Ninguna de mis declaraciones en el bloque catch o finally se están ejecutando.

try {
jdbcTemplate.execute(“select pg_sleep(40)”);
} catch(DataAccessException e) {
LOGGER.info(e.getMessage(), e);
Thread.sleep(30000);
jdbcTemplate.execute(“select pg_sleep(10)”);
LOGGER.info(“Executed fall back case”);
} finally {
jdbcTemplate.execute(“select 1”);
}

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Según la información proporcionada, parece que cambiar el valor de removeAbandonedTimeout a 1800 segundos ya ha resuelto la mayoría de los problemas, pero aún hay ocurrencias esporádicas de conexiones abandonadas.

    La configuración actual del grupo parece razonable y bien configurada. Sin embargo, el problema puede estar relacionado con el hecho de que la propiedad testOnBorrow está establecida en verdadero, lo que significa que se ejecuta una consulta de validación cada vez que se obtiene una conexión del grupo. Esta consulta de validación puede añadir sobrecarga adicional y retrasos cuando se necesita una conexión, especialmente si el servidor de la base de datos está bajo carga pesada.

    Una posible solución para este problema sería aumentar el número de conexiones inactivas en el grupo estableciendo la propiedad minIdle a un valor más alto, como 5 o 10. Esto aseguraría que siempre haya un número suficiente de conexiones disponibles para su uso, reduciendo las posibilidades de que el grupo de conexión se quede vacío y cause tiempos de espera de conexión. Además, la propiedad testOnBorrow se puede establecer en falso, lo que permitiría tomar prestadas conexiones del grupo sin realizar una consulta de validación cada vez.

    Otra posible solución sería implementar un mecanismo de reintento de conexión dentro del bloque de captura, utilizando un bucle que intente ejecutar la consulta un cierto número de veces antes de rendirse. Esto evitaría que consultas posteriores fallen inmediatamente con excepciones de conexión abandonada y permitiría más tiempo al temporizador de conexión abandonada para eliminar las conexiones abandonadas.

    En general, es importante monitorear cuidadosamente el rendimiento de la aplicación y la base de datos, y ajustar la configuración del grupo de conexión según sea necesario para garantizar un rendimiento y una confiabilidad óptimos.

Comments are closed.