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.
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".
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
