java - timebetweenevictionrunsmillis - Problema de interbloqueo en DBCP implementado en Tomcat
tomcat jdbc tutorial (5)
Estoy usando el origen de datos DBCP (con la configuración predeterminada) en la configuración de Spring para administrar mis conexiones a la base de datos, y me encuentro con una condición de interbloqueo cuando aumenta el número de clientes.
Encontré que hay un problema de interbloqueo en DBCP 1.2.1 que estaba usando, que se suponía que se resolvía en 1.4. Así que actualicé a 1.4, pero el problema aún persiste.
En el volcado de hilos, hay muchos subprocesos bloqueados con el siguiente seguimiento de pila en la parte superior:
java.lang.Thread.State: WAITING on org.apache.commons.pool.impl.GenericObjectPool$Latch@b6b09e
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:200)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:350)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:261)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:160)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:631)
Cualquier sugerencia es bienvenida!
¿Se aseguró de que la versión de commons-pool coincida con la versión de dbcp?
Además, no veo un interbloqueo en el seguimiento de pila, simplemente parece que tienes hilos en espera de que las conexiones se liberen ... ¿Cuántos hilos estás intentando conectar al mismo tiempo? ¿Cuántas conexiones has configurado para el grupo, etc.?
En la depuración de este tipo de casos, también es útil observar qué están haciendo los hilos que han obtenido una conexión.
Creo que esto se debe a que no se cierran las conexiones en el código de tu aplicación, por lo que simplemente te quedas sin conexiones en el grupo. Tal vez debería intentar establecer la propiedad "removeAbandoned" en DBCP. Esto se documenta en http://commons.apache.org/dbcp/configuration.html como
Al establecer esto en verdadero, se pueden recuperar conexiones de bases de datos de aplicaciones mal escritas que no logran cerrar una conexión.
¡La mejor de las suertes!
Incrementar la carga en la aplicación es un requisito cada vez mayor para las conexiones concurrentes. Como sus hilos se cuelgan en borrowConnection()
, significa que no tiene suficientes ActiveConnections
disponibles.
Incrkease maxActive
en las propiedades de su maxActive
de datos y establezca WHEN_EXHAUSTED_BLOCK
en algún momento como 600ms - 1000ms
. Obtendrá la excepción No element available
solo después de transcurridos 600 ms -1000 ms.
Me enfrentaba a problemas similares y esto se resolvió siguiendo los pasos
Cierre todos los recursos de la base de datos en la secuencia adecuada
resultSet.close(); statement.close(); connection.close();
Diferentes controladores se implementan de manera diferente, algunos controladores aún se transferirían a la conexión si el conjunto de resultados subyacente no está cerrado.
- Los ajustes por defecto de Apache DBCP deben ser ajustados
dataSource.setDefaultAutoCommit(true);
dataSource.setMaxActive(700); // make sure db server has it 800 dataSource.setRemoveAbandoned(true); dataSource.setTestOnBorrow(true); dataSource.setLogAbandoned(true); dataSource.setTestWhileIdle(true); dataSource.setTestOnReturn(true); dataSource.setRemoveAbandonedTimeout(60);
Asegúrese de que el servidor de la base de datos pueda permitir más de 50 conexiones más que el número especificado en setMaxActive
ya que el dbcp le da primero a x
nuevas conexiones y luego intenta limpiar las conexiones que excedan el número de setMaxActive
. En la limpieza, dbcp muestra que todas las conexiones no se cerraron en el servidor de registro / consola.
c3p0 a c3p0 , hace unos años. Puedes intentar eso. Creo que no tuvo que cambiar mucho, es solo un juego de configuración.
Hilo algo relacionado, opciones de agrupación de conexiones con JDBC: DBCP vs C3P0 . Bueno, en realidad lo hice relacionado.
[editado, 19/10/12]
Tomcat 7 tiene un grupo de conexiones decente, el grupo de conexiones JDBC de Tomcat .