Mastering Druid: Configuring and Stress‑Testing the Alibaba JDBC Connection Pool

This article introduces Alibaba's Druid JDBC connection pool, walks through a basic Java usage example, details essential configuration parameters, and demonstrates a multithreaded concurrency test to evaluate performance and stability in MySQL environments.

FunTester
FunTester
FunTester
Mastering Druid: Configuring and Stress‑Testing the Alibaba JDBC Connection Pool

Druid Overview

Druid is an open‑source database connection pool from Alibaba, designed with built‑in monitoring that does not compromise performance. It offers high throughput, reliability, rich management features, security against SQL injection, and extensibility for various database types.

Simple Usage Example

static void main(String[] args) {
    // Create Druid data source
    DruidDataSource dataSource = new DruidDataSource();
    // Configure connection information
    dataSource.setUrl("jdbc:mysql://localhost:3306/funtester");
    dataSource.setUsername("root");
    dataSource.setPassword("funtester");
    // Get a connection
    Connection connection = dataSource.getConnection();
    // Execute SQL
    Statement statement = connection.createStatement();
    def query = statement.executeQuery("select id, uid, create_time  from record order by id desc limit 10;");
    while (query.next()) {
        println("id: ${query.getInt(1)}, uid: ${query.getInt(2)}, create_time: ${query.getTimestamp(3)}");
    }
    query.close();
    // Close resources
    statement.close();
    connection.close();
}

The example shows that only a few lines of code are needed to configure and use Druid in a Java application.

Druid Configuration Parameters

Druid provides a rich set of configurable properties. Below are the most commonly used ones, grouped by purpose.

Basic Settings driverClassName: JDBC driver class name. url: Database connection URL. username: Database user name. password: Database password.

Initialization Settings initialSize: Number of connections created when the pool starts (default 0). maxActive: Maximum number of active connections (default 8). maxIdle: Maximum number of idle connections; too large may slow the system, increase for batch queries (default 8).

Timeout Settings maxWait: Maximum wait time (ms) for a connection before throwing an exception (default unlimited). timeBetweenEvictionRunsMillis: Interval between idle‑connection eviction checks (default 1 minute). minEvictableIdleTimeMillis: Minimum time a connection may stay idle before being eligible for eviction (default 30 minutes).

Test Settings testWhileIdle: Whether to test connections while idle (default false, costly). testOnBorrow: Whether to test a connection when borrowed (default true, recommended false for better performance). testOnReturn: Whether to test a connection when returned (default false).

Abandoned Connection Recovery removeAbandoned: Enable removal of abandoned connections (default false). removeAbandonedTimeout: Timeout (seconds) after which an abandoned connection is reclaimed (default 300). logAbandoned: Log abandoned connection reclamation (default false).

Other Settings filters: Plugins such as stat, log4j, wall for statistics, logging, and SQL‑injection protection. validationQuery: SQL used to validate a connection, e.g., select 1. accessToUnderlyingConnectionAllowed: Allow access to the raw JDBC connection (default false).

Adjust these parameters according to the application's workload; for long‑idle scenarios, reduce maxIdle, and for high concurrency, increase maxActive.

Concurrency Demonstration

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.funtester.frame.SourceCode;
import java.sql.Connection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class DruidConcurrencyDemo extends SourceCode {
    private static DruidDataSource dataSource;
    static {
        try {
            // Configure Druid properties
            Properties properties = new Properties();
            properties.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, "com.mysql.cj.jdbc.Driver");
            properties.put(DruidDataSourceFactory.PROP_URL, "jdbc:mysql://localhost:3306/funtester");
            properties.put(DruidDataSourceFactory.PROP_USERNAME, "root");
            properties.put(DruidDataSourceFactory.PROP_PASSWORD, "funtester");
            properties.put(DruidDataSourceFactory.PROP_MAXACTIVE, "10");
            properties.put(DruidDataSourceFactory.PROP_INITIALSIZE, "3");
            properties.put(DruidDataSourceFactory.PROP_MAXWAIT, "5000");
            // Create the pool
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void main(String[] args) throws InterruptedException {
        int threadCount = 4; // simulate 4 concurrent requests
        CountDownLatch latch = new CountDownLatch(threadCount);
        ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
        // Concurrently acquire connections
        for (int i = 0; i < threadCount; i++) {
            executorService.execute(() -> {
                try {
                    Connection connection = dataSource.getConnection();
                    Thread.sleep(1000); // simulate 1‑second work
                    output("Active connections: " + dataSource.getActiveCount());
                    output("Idle connections: " + dataSource.getPoolingCount());
                    connection.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    latch.countDown();
                }
            });
        }
        latch.await();
        executorService.shutdown();
        // Final pool status
        output("Active connections: " + dataSource.getActiveCount());
        output("Idle connections: " + dataSource.getPoolingCount());
    }
}

Sample console output shows how active and idle connection counts change during the test. If the deprecated property PROP_MAXIDLE is set, Druid logs a deprecation warning such as "main maxIdle is deprecated".

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaconcurrencyPerformance TestingConnection PoolJDBCDruid
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.