If your Java application frequently opens short-lived connections to ApsaraDB RDS for MySQL, or hits the instance's maximum connection limit, Druid keeps a pool of reusable connections so your application doesn't pay the cost of a full TCP handshake on every request.
Prerequisites
Before you begin, ensure that you have:
-
Java Development Kit (JDK) 1.8 or later installed on your application server
-
The server's IP address added to the RDS instance's IP address whitelist. See Configure an IP address whitelist
If your application runs on an Elastic Compute Service (ECS) instance in the same region and virtual private cloud (VPC) as the RDS instance, no whitelist configuration is required.
Set up the project
The following steps use an Apache Maven project as an example. A Maven project stores Java source files under src/main/java and resource files under src/main/resources. The pom.xml file manages project dependencies.
Add Druid as a dependency
Add the following to the dependencies section in pom.xml. Use Druid 1.2.13 or later.
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.19</version>
</dependency>
If you use `druid-spring-boot-starter`, exclude the transitive Druid dependency it brings in, then re-add Druid explicitly so the version is controlled:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.19</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.19</version>
</dependency>
Connect to an RDS instance
Step 1: Create the connection pool configuration file
Create druid.properties in src/main/resources with the following content.
To find your RDS instance's endpoint and port, see View and manage instance endpoints and ports.
# Driver class — do not modify
driverClassName=com.mysql.jdbc.Driver
# Replace with your RDS endpoint, database name, username, and password
url=jdbc:mysql://rm-bp**************.mysql.rds.aliyuncs.com:3306/database
username=****
password=****
# Connection pool sizing
initialSize=20
minIdle=20
maxActive=100
# Connection lifecycle
phyTimeoutMillis=3600000
# Wait and timeout settings
maxWait=5000
connectTimeout=20000
socketTimeout=60000
# Idle connection validation
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
# PreparedStatement cache
poolPreparedStatements=true
maxPoolPreparedStatementPerConnectionSize=100
Step 2: Initialize the connection pool and access the database
In src/main/java, create the DruidPoolDemo class. It loads druid.properties from the classpath, initializes the pool with DruidDataSourceFactory, and exposes a DataSource for subsequent database operations.
package com.aliyun.rdsfinops.collector.impl;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class DruidPoolDemo {
private static DataSource dataSource = null;
String tableName = "sql_table_test";
// Load druid.properties and initialize the connection pool at class load time
static {
Properties properties = new Properties();
InputStream inputStream = DruidPoolDemo.class.getClassLoader()
.getResourceAsStream("druid.properties");
try {
properties.load(inputStream);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
/*
Database operations are defined in the following methods:
Create a table: public void createTable()
Insert data: public void insertData()
Query data: public void selectData()
Delete data: public void deleteData()
*/
}
Connection pool parameters
Run a full performance test against your production workload before changing parameter values on a live system.
Recommended parameters
These parameters have non-obvious defaults or incorrect default values that can silently degrade stability. Review and set them explicitly.
| Parameter | Default | Recommended | Description |
|---|---|---|---|
initialSize |
0 | 20–80 | Connections established at startup. Set to 60–80% of your average concurrent connection count so the pool is ready to handle load immediately after the application starts. |
minIdle |
0 | 20–80 | Minimum idle connections kept in reserve for burst traffic. Match this to initialSize or to the connection count the Java Virtual Machine (JVM) holds during low-load periods. |
maxActive |
8 | 100 | Maximum active connections. Set this to the peak concurrent connection count your database can handle, with some headroom for traffic spikes. |
phyTimeoutMillis |
-1 (no limit) | 3,600,000–28,800,000 | Maximum time (ms) a physical connection can stay alive before Druid forcibly closes and recreates it. The default value -1 specifies that connections are always available for reuse. Configure this parameter based on your business requirements. This parameter is used to prevent long-lived idle connections and save resources. |
maxWait |
-1 (wait forever) | 5,000 | Maximum time (ms) to wait for a connection when the pool is exhausted. Never set this to -1 (threads block indefinitely) or 0 (requests fail immediately). In normal conditions, acquiring a connection takes 10–30 ms; 5,000 ms gives ample buffer. |
connectTimeout |
10,000 | 3,000 | TCP connection timeout (ms) when establishing a new connection to the RDS server. Adjust based on network latency between your application and the instance. |
socketTimeout |
10,000 | 10,000–60,000 | Time (ms) to wait for the database to respond after sending a SQL statement. Do not set this too low — if a query legitimately runs longer, the connection will be abandoned. Investigate slow queries before reducing this value. |
testWhileIdle |
false | true | We recommend that you set this parameter to true. The connection pool periodically checks the status of idle connections. |
Optional parameters
| Parameter | Default | Recommended | Description |
|---|---|---|---|
poolPreparedStatements |
true | true | Caches PreparedStatement objects per connection. Reduces SQL compilation overhead when the same statements run repeatedly, and helps prevent SQL injection. Disable if your queries vary significantly or involve large result sets that would consume excessive JVM memory. |
maxPoolPreparedStatementPerConnectionSize |
10 | 100 | Maximum cached PreparedStatement objects per connection. Increase if your application runs many distinct parameterized queries. Avoid very large values to prevent memory pressure. |
Default parameters
These parameters work well at their defaults for most use cases. Modify them only if you have a specific requirement.
| Parameter | Default | Description |
|---|---|---|
failFast |
false | When false, connection requests wait up to maxWait before failing. Set to true in error-sensitive, high-concurrency scenarios where you want immediate failure instead of waiting — typically used together with maxWaitThreadCount. |
timeBetweenEvictionRunsMillis |
60,000 | Interval (ms) at which the pool checks idle connections against minEvictableIdleTimeMillis. The default is suitable for most workloads. |
Database operations
Add these methods to the DruidPoolDemo class to perform common database operations on the sql_table_test table.
Create a table
String tableName = "sql_table_test";
public void createTable() throws SQLException {
try (Connection connection = dataSource.getConnection()) {
try (Statement statement = connection.createStatement()) {
String sql = "create table if not exists " + tableName
+ "(id VARCHAR(255), name VARCHAR(255), PRIMARY KEY (id))";
int ret = statement.executeUpdate(sql);
System.out.println(ret);
}
}
}
Insert data
public void insertData() {
try (Connection connection = dataSource.getConnection()) {
String sql = "insert into " + tableName + "(id,name) values(?,?)";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, "aa");
ps.setString(2, "bb");
int ret = ps.executeUpdate();
System.out.println(ret);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
Query data
public void selectData() throws SQLException {
try (Connection connection = dataSource.getConnection()) {
String sql = "select * from " + tableName + " where id=?";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, "aa");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
System.out.println("id=" + id);
System.out.println("name=" + name);
}
}
}
}
Delete data
public void deleteData() {
try (Connection connection = dataSource.getConnection()) {
String sql = "delete from " + tableName + " where id=?";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, "aa");
ps.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
What's next
-
Use DBUtils to connect to an ApsaraDB RDS for MySQL instance — Python connection pool
-
Use Go-MySQL-Driver to connect to an ApsaraDB RDS for MySQL instance — Go driver package
-
Configure the connection pooling feature — Server-side connection pooling via the ApsaraDB RDS database proxy