Saltar al contenido

¿Cómo depurar / registrar las conexiones del grupo de conexiones JDBC de Tomcat?

Solución:

Después de mucha investigación, puedo encontrar 3 formas de registrar y monitorear el grupo de conexiones de la base de datos.

https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html

  1. Monitoreo usando Bota de primavera propiedades.

  2. Monitoreo usando JMX (Extensiones de administración de Java) (como sugirió @nitin)

  3. Monitoreo usando Primavera Aspectos.

1st Way: Monitoreo usando las propiedades de Spring Boot.

Encontré a continuación las propiedades de arranque de Spring que serán muy útiles para registrar y monitorear el grupo de conexiones de la base de datos.

Estas propiedades (y algunas más también) fueron no documentado. Consulte el problema de github a continuación para obtener más detalles. https://github.com/spring-projects/spring-boot/issues/1829

#Maximum no.of active connections
spring.datasource.max-active=10

#Log the stack trace of abandoned connection
spring.datasource.log-abandoned=true

#Remove abandoned connection,So, new connection will be created and made available to threads which are waiting for DB connection
spring.datasource.remove-abandoned=true

#If any connection is not used for 10 seconds, consider that connection as "abandoned"
spring.datasource.remove-abandoned-timeout=10 

#Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.max-wait=1000

Esta lista contiene más propiedades relacionadas con solo fuente de datos. (tomado del enlace de arriba)

spring.datasource.abandon-when-percentage-full
spring.datasource.access-to-underlying-connection-allowed
spring.datasource.alternate-username-allowed
spring.datasource.auto-commit
spring.datasource.catalog
spring.datasource.commit-on-return
spring.datasource.connection-customizer
spring.datasource.connection-customizer-class-name
spring.datasource.connection-init-sql
spring.datasource.connection-init-sqls
spring.datasource.connection-properties
spring.datasource.connection-test-query
spring.datasource.connection-timeout
spring.datasource.data-source
spring.datasource.data-source-class-name
spring.datasource.data-source-j-n-d-i
spring.datasource.data-source-properties
spring.datasource.db-properties
spring.datasource.default-auto-commit
spring.datasource.default-catalog
spring.datasource.default-read-only
spring.datasource.default-transaction-isolation
spring.datasource.driver-class-loader
spring.datasource.fair-queue
spring.datasource.idle-timeout
spring.datasource.ignore-exception-on-pre-load
spring.datasource.init-s-q-l
spring.datasource.initialization-fail-fast
spring.datasource.isolate-internal-queries
spring.datasource.jdbc-interceptors
spring.datasource.jdbc-url
spring.datasource.jdbc4-connection-test
spring.datasource.leak-detection-threshold
spring.datasource.log-abandoned
spring.datasource.log-validation-errors
spring.datasource.log-writer
spring.datasource.login-timeout
spring.datasource.max-age
spring.datasource.max-lifetime
spring.datasource.max-open-prepared-statements
spring.datasource.maximum-pool-size
spring.datasource.metrics-tracker-class-name
spring.datasource.minimum-idle
spring.datasource.num-tests-per-eviction-run
spring.datasource.pool-name
spring.datasource.pool-prepared-statements
spring.datasource.pool-properties
spring.datasource.propagate-interrupt-state
spring.datasource.read-only
spring.datasource.record-metrics
spring.datasource.register-mbeans
spring.datasource.remove-abandoned
spring.datasource.remove-abandoned-timeout
spring.datasource.rollback-on-return
spring.datasource.suspect-timeout
spring.datasource.test-on-connect
spring.datasource.thread-factory
spring.datasource.transaction-isolation
spring.datasource.use-disposable-connection-facade
spring.datasource.use-equals
spring.datasource.use-lock
spring.datasource.validation-interval
spring.datasource.validation-query-timeout
spring.datasource.validator
spring.datasource.validator-class-name
spring.datasource.xa
spring.datasource.xa.data-source-class-name
spring.datasource.xa.properties

2nd Way: Monitoreo usando JMX (Extensiones de administración de Java)

El grupo Tomcat JDBC proporciona un MBean, a saber, ConnectionPoolMBean.

https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.html

Spring Boot registra JMX MBeans automáticamente, por lo que no es necesario registrar / exportar este MBean al servidor MBean. Simplemente abra la JConsole que viene con JDK, Para abrir, En Windows-> Símbolo del sistema -> jconsole, eso es todo. Consulte la captura de pantalla a continuación para obtener más información.

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Este MBean también notifica cada vez que se abandona una conexión, falla la conexión, cuando una consulta está tardando mucho tiempo, etc. Consulte la captura de pantalla a continuación.

ingrese la descripción de la imagen aquí

3rd Way: Monitoreo usando Spring Aspects (solo para desarrollo / entorno de control de calidad).

Utilizo este aspecto para registrar el grupo de conexiones TomcatJdbc.

Creé un Spring Aspect que interceptará todas las llamadas a la base de datos. seguramente afectará el rendimiento.

Por lo tanto, utilice este aspecto en el entorno de desarrollo / control de calidad,comenta este método cuando no sea necesario (por ejemplo: durante la implementación de producción).

@Before("execution(* com.test.app.db.dao.*.*(..))")
    public void logBeforeConnection(JoinPoint jp) throws Throwable {
        String methodName = "";
        methodName += jp.getTarget().getClass().getName();
        methodName += ":";
        methodName += jp.getSignature().getName();
        logger.info("before method call : " + methodName +  " : number of connections in use by the application (active) : "+ tomcatJdbcPoolDataSource.getNumActive());
        logger.info("before method call : " + methodName +  " : the number of established but idle connections : "+ tomcatJdbcPoolDataSource.getNumIdle());
        logger.info("before method call : " + methodName +  " : number of threads waiting for a connection : "+ tomcatJdbcPoolDataSource.getWaitCount());
    }


@After("execution(* com.test.app.db.dao.*.*(..)) ")
public void logAfterConnection(JoinPoint jp) throws Throwable {
    String methodName = "";
    methodName += jp.getTarget().getClass().getName();
    methodName += ":";
    methodName += jp.getSignature().getName();
    logger.info("after method call : " + methodName +  " : number of connections in use by the application (active) : "+ tomcatJdbcPoolDataSource.getNumActive());
    logger.info("after method call : " + methodName +  " : the number of established but idle connections : "+ tomcatJdbcPoolDataSource.getNumIdle());
    logger.info("after method call : " + methodName +  " : number of threads waiting for a connection : "+ tomcatJdbcPoolDataSource.getWaitCount());
    //tomcatJdbcPoolDataSource.checkAbandoned();
}

Ahora, puede identificar fácilmente la llamada de base de datos particular que crea una fuga de conexión en su aplicación.

Gracias @Sundararaj Govindasamy por una gran respuesta. En base a eso, creé un componente en mi aplicación Spring Boot para depurar la información de mi base de datos.

import org.apache.tomcat.jdbc.pool.DataSource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DataSourceAspectLogger {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private DataSource ds;

    @Before("execution(* br.com.foo.core.repository.*.*(..))")
    public void logBeforeConnection(JoinPoint jp) throws Throwable {
        logDataSourceInfos("Before", jp);
    }

    @After("execution(* br.com.foo.core.repository.*.*(..)) ")
    public void logAfterConnection(JoinPoint jp) throws Throwable {
        logDataSourceInfos("After", jp);
    }

    public void logDataSourceInfos(final String time, final JoinPoint jp) {
        final String method = String.format("%s:%s", jp.getTarget().getClass().getName(), jp.getSignature().getName());
        logger.info(String.format("%s %s: number of connections in use by the application (active): %d.", time, method, ds.getNumActive()));
        logger.info(String.format("%s %s: the number of established but idle connections: %d.", time, method, ds.getNumIdle()));
        logger.info(String.format("%s %s: number of threads waiting for a connection: %d.", time, method, ds.getWaitCount()));
    }
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *