example conexiones java eclipse tomcat jdbc connection-pooling

java - example - pool de conexiones tomcat 8



El grupo de conexiones JDBC se queda sin conexiones cuando Context reload="true" está habilitado en Tomcat (1)

LA SOLUCIÓN (tl; dr)

Para resolver este problema, agregue un atributo closeMethod (documentado here ) con el valor " close " al elemento Resource en el archivo context.xml.

Aquí está el contenido correcto de mi archivo /META-INF/context.xml:

<Context> <!-- Configuration for the Tomcat JDBC Connection Pool --> <Resource name="jdbc/someDB" type="javax.sql.DataSource" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/somedb" username="postgres" password="12345" maxActive="100" minIdle="10" initialSize="10" validationQuery="SELECT 1" validationInterval="30000" removeAbandoned="true" removeAbandonedTimeout="60" abandonWhenPercentageFull="50" closeMethod="close" /> </Context>

Preste atención al atributo closeMethod . ¡Lo probé y ahora el número de conexiones se mantiene ESTRICTAMENTE como se define en el archivo context.xml !

NOTA
Hay un momento (relacionado con JNDI) que puede ser atendido. Vea la ACTUALIZACIÓN 3 para la descripción completa.

Respuesta larga

OK, encontré la solución anterior gracias al comisionado de Apache Tomcat, Konstantin Kolinko . Informé de este problema como un error de Apache Tomcat en ASF Bugzilla y resultó que no es un error (ver ACTUALIZACIÓN 1).

=== ACTUALIZACIÓN 1 (2012-12-03) también conocido como "Una nueva esperanza" ===

Bueno, todavía resultó ser un error . Mark Thomas , el gerente de lanzamiento de Apache Tomcat 7, confirmed que (cita):

"Este es un error de pérdida de memoria en jdbc-pool. Las instancias de PoolCleaner están reteniendo referencias a ConnectionPool impidiendo que sea GC''d.
...
Esto se ha corregido en trunk y 7.0.x y se incluirá en 7.0.34 en adelante. "

Entonces, si tiene una versión anterior de Tomcat (menos de 7.0.34), use la solución anterior, de lo contrario, comenzando con Apache Tomcat versión 7.0.34, no debería haber problemas como el que describí. (ver ACTUALIZACIÓN 2)

=== UPDATE 2 (2014-01-13) aka "The Issue Strikes Back" ===

Parece que el problema descrito inicialmente en mi informe de fallas aún está presente incluso para la última versión de Apache Tomcat 7.0.50 y también lo reproduje con Tomcat 7.0.47 (gracias a Miklos Krivan por señalarlo). Aunque ahora Tomcat a veces logra cerrar conexiones adicionales después de volver a cargar, y algunas veces la cantidad de conexiones aumenta después de una recarga y luego se mantiene estable, pero finalmente este comportamiento aún no es confiable.

Todavía podría reproducir el problema descrito inicialmente (aunque de nuevo no es tan fácil: puede estar relacionado con la frecuencia de recargas sucesivas). Parece que solo es cuestión de tiempo, es decir, si Tomcat tiene suficiente tiempo después de volver a cargar, administra el grupo de conexiones más o menos como debería. Como Mark Thomas mencionó en su comment (cita): "De acuerdo con los documentos de closeMethod, ese método existe únicamente para acelerar la liberación de recursos que de otra forma serían liberados por GC". (fin de cita), y parece que la velocidad es el factor determinante.

Al usar la solución presentada por Konstantin Kolinko (para usar closeMethod = "cerrar") todo FUNCIONA muy bien, y el número de conexiones reservadas se mantiene ESTRICTAMENTE como se define en el archivo context.xml. Por lo tanto, parece que el uso de closeMethod = "close" es la ÚNICA forma (en este momento) para evitar quedarse sin conexiones después de la recarga de contexto.

=== UPDATE 3 (2014-01-13) alias "Return of the Tomcat Release Manager" ===

El misterio detrás del comportamiento descrito en la ACTUALIZACIÓN 2 está resuelto. Se han aclarado más detalles ahora después de recibir una reply de Mark Thomas (gerente de publicación de Tomcat). Espero que esta sea la última actualización. Así que el error fue reparado como se mencionó en la ACTUALIZACIÓN 1. Estoy publicando la parte esencial de la respuesta de Mark aquí como una cita (el énfasis es mío):

La fuga de memoria real encontrada al investigar este error se ha corregido en 7.0.34 en adelante según los comentarios # 4 a # 6.

El problema de que las conexiones no se cierren durante la recarga es el resultado de la especificación J2EE para los recursos JNDI y, por lo tanto, esta parte del informe de errores no es válida. Estoy restaurando el estado de este error para repararlo para que refleje que la pérdida de memoria que existió ha sido reparada.

Para ampliar el motivo por el cual la falla de cerrar inmediatamente la conexión después de la recarga no es válida, la especificación J2EE no proporciona ningún mecanismo para que el contenedor le diga al recurso que ya no es necesario. Por lo tanto, todo lo que el contenedor puede hacer es hacer referencias claras al recurso y esperar a que se recoja basura (lo que activará el cierre del grupo y las conexiones asociadas). La recogida de basura se produce a veces determinada por la JVM, por lo que es necesario un tiempo indeterminado para que se cierren las conexiones después de una recarga de contexto, ya que una recolección de basura puede no producirse durante un tiempo.

Tomcat ha agregado el atributo JNDI específico CloseMethod de Tomcat que se puede utilizar para activar el cierre explícito de un recurso JNDI cuando se detiene un contexto. Si no es aceptable esperar a que GC limpie los recursos, simplemente use este parámetro . Tomcat no usa esto de forma predeterminada, ya que puede tener efectos secundarios inesperados y no deseados para algunos recursos JNDI .

Si desea ver un mecanismo estándar proporcionado para indicarle a los recursos de JNDI que ya no son necesarios, entonces necesita presionar al grupo de expertos de J2EE.

Conclusión

Solo use la solución presentada al comienzo de esta publicación (pero, por si acaso, tenga en cuenta el problema relacionado con JNDI que puede surgir teóricamente de su uso).

Solución alternativa

Michael Osipov sugirió usar su CloseableResourceListener , que evita las pérdidas de memoria causadas por los recursos abiertos durante el despliegue de las aplicaciones web. Entonces también puedes intentarlo.

RENUNCIA
Los alias de las ACTUALIZACIONES se inspiraron en la serie de películas Star Wars . Todos los derechos pertenecen a sus respectivos dueños.

Estoy desarrollando una aplicación web Java EE en Eclipse Juno. He configurado Tomcat para usar el conjunto de conexiones JDBC (org.apache.tomcat.jdbc.pool) junto con la base de datos PostgreSQL. Aquí están las configuraciones en META-INF / context.xml de mi proyecto:

<?xml version="1.0" encoding="UTF-8"?> <Context> <!-- Configuration for the Tomcat JDBC Connection Pool --> <Resource name="jdbc/someDB" type="javax.sql.DataSource" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/somedb" username="postgres" password="12345" maxActive="100" minIdle="10" initialSize="10" validationQuery="SELECT 1" validationInterval="30000" removeAbandoned="true" removeAbandonedTimeout="60" abandonWhenPercentageFull="50" /> </Context>

Mi aplicación se implementa en Tomcat utilizando Eclipse, y en context.xml de Tomcat un atributo recargable se establece en "verdadero" para volver a cargar automáticamente la aplicación web si se detecta un cambio:

<Context reloadable="true">

Me he dado cuenta de que cada vez que se produce la recarga automática mencionada anteriormente, se reservan 10 conexiones más a PostgreSQL db (porque en el contexto de la aplicación webapp initialSize = "10"). Entonces, después de 10 cambios, se lanza una PSQLException:

org.postgresql.util.PSQLException: FATAL: sorry, too many clients already ...

Si reinicio Tomcat manualmente, todo está bien y solo quedan 10 conexiones reservadas.

¿Alguien conoce la forma de solucionar este problema, por lo que podría ser posible desarrollarlo con el conjunto recargable en "verdadero" y no causar la agrupación de más conexiones cada vez que se recargue el contexto?

Agradecería cualquier ayuda.

PS Apache Tomcat Versión 7.0.32