Configuración de Druid Connection Pool en Aplicaciones Spring Boot

Druid es un componente JDBC de código abierto desarrollado por Alibaba que funciona como un pool de conexiones de base de datos de alto rendimiento. Se compone principalmente de tres elementos fundamentales: DruidDriver (un proxy que permite extensiones mediante filtros), DruidDataSource (el pool de conexiones gestionable) y SQLParser (un motor de análisis de sentencias SQL).

Ventajas de utilizar Druid

  • Monitoreo avanzado: Incluye StatFilter, un plugin capaz de generar estadísticas detalladas sobre el rendimiento de las consultas SQL, facilitando el análisis en entornos de producción.
  • Sustitución eficiente: Actúa como un reemplazo moderno y escalable para bibliotecas más antiguas como DBCP o C3P0.
  • Seguridad: Soporta el uso de PasswordCallback para evitar el almacenamiento de contraseñas en texto plano dentro de los archivos de configuración.
  • Registro de actividad: Ofrece diversos LogFilters compatibles con Log4j, JdkLog y Common-Logging para supervisar el acceso a los datos.
  • Extensibilidad: Su arquitectura basada en Filter-Chain permite inyectar lógica personalizada en la capa JDBC de forma sencilla.

Dependencias del Proyecto

Para integrar Druid en un proyecto Spring Boot, es necesario incluir las dependencias correspondinetes en el archivo pom.xml:

<!-- Conector de Base de Datos MySQL -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- Starter de Spring Data JPA -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Librería Principal de Druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>

Configuración del Entorno (application.properties)

La parametrización del pool de conexiones se define externamente para facilitar su mantenimiento sin necesidad de recompilar el código:

# Configuración básica del origen de datos
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/mi_base_datos
spring.datasource.username=db_user
spring.datasource.password=db_pass
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver

# Parámetros de optimización del pool
spring.datasource.initial-size=10
spring.datasource.min-idle=10
spring.datasource.max-active=50
spring.datasource.max-wait=45000

# Ciclos de mantenimiento y validación
spring.datasource.time-between-eviction-runs-millis=60000
spring.datasource.min-evictable-idle-time-millis=300000
spring.datasource.validation-query=SELECT 1
spring.datasource.test-while-idle=true
spring.datasource.test-on-borrow=false
spring.datasource.test-on-return=false

# Caché de sentencias preparadas (PSCache)
spring.datasource.pool-prepared-statements=true
spring.datasource.max-pool-prepared-statement-per-connection-size=25

# Configuración de filtros (monitoreo y firewall SQL)
spring.datasource.filters=stat,wall,slf4j
spring.datasource.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=3000

Clase de Configuración Java

Para instanciar el DataSource dentro del contenedor de Spring, se crea una clase de configuración que asigne las propiedades definidas anteriormente:

@Configuration
public class DataSourceConfig {

    private final Logger log = LoggerFactory.getLogger(DataSourceConfig.class);

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String user;

    @Value("${spring.datasource.password}")
    private String pass;

    @Value("${spring.datasource.driverClassName}")
    private String driver;

    @Value("${spring.datasource.initial-size}")
    private int initSize;

    @Value("${spring.datasource.min-idle}")
    private int minIdle;

    @Value("${spring.datasource.max-active}")
    private int maxActive;

    @Value("${spring.datasource.max-wait}")
    private int maxWait;

    @Value("${spring.datasource.filters}")
    private String sqlFilters;

    @Bean
    @Primary
    public DataSource customDataSource() {
        DruidDataSource druidPool = new DruidDataSource();

        druidPool.setUrl(url);
        druidPool.setUsername(user);
        druidPool.setPassword(pass);
        druidPool.setDriverClassName(driver);

        // Aplicación de configuraciones técnicas
        druidPool.setInitialSize(initSize);
        druidPool.setMinIdle(minIdle);
        druidPool.setMaxActive(maxActive);
        druidPool.setMaxWait(maxWait);

        try {
            druidPool.setFilters(sqlFilters);
            log.info("Filtros de Druid configurados exitosamente: {}", sqlFilters);
        } catch (SQLException e) {
            log.error("Error al inicializar los filtros de monitoreo de Druid", e);
        }

        return druidPool;
    }
}

Habilitación del Panel de Control de Druid

Druid provee una interfaz web integrada para visualizar las estadísticas del pool. Se configura mediante un Servlet y un Filtro:

Configuración del Servlet de Monitoreo:

@WebServlet(urlPatterns = "/druid-dashboard/*", 
    initParams = {
        @WebInitParam(name = "allow", value = "127.0.0.1"), // Acceso restringido a localhost
        @WebInitParam(name = "loginUsername", value = "admin_root"),
        @WebInitParam(name = "loginPassword", value = "secure_pass"),
        @WebInitParam(name = "resetEnable", value = "false")
    })
public class DruidMonitorServlet extends StatViewServlet {
    private static final long serialVersionUID = 1L;
}

Configuración del Filtro Estadístico:

@WebFilter(filterName = "druidWebFilter", urlPatterns = "/*",
    initParams = {
        @WebInitParam(name = "exclusions", value = "*.js,*.css,*.png,*.jpg,*.ico,/druid-dashboard/*")
    })
public class DruidWebStatFilter extends WebStatFilter {
    // Clase para filtrar recursos estáticos del monitoreo
}

Etiquetas: SpringBoot Druid java JDBC ConnectionPool

Publicado el 10-30 21:08