使用Java連接池Druid連接數(shù)據(jù)庫
如果您的應(yīng)用側(cè)主要使用Java語言,且數(shù)據(jù)庫連接創(chuàng)建頻繁(例如短連接場景)或連接數(shù)量較大(大于MySQL數(shù)據(jù)庫的連接數(shù)限制),您可以使用Java連接池Druid連接數(shù)據(jù)庫,降低連接建立頻率以減少數(shù)據(jù)庫主線程的開銷。
前提條件
應(yīng)用服務(wù)器已安裝Java環(huán)境且JDK版本在1.8及以上。
已將服務(wù)器IP地址添加至RDS實例白名單中,詳情請參見設(shè)置IP白名單。
說明若您的應(yīng)用程序部署在阿里云ECS服務(wù)器上,且ECS與RDS已實現(xiàn)內(nèi)網(wǎng)互通(ECS與RDS實例的地域、VPC均相同),則無需設(shè)置IP白名單。
準備工作
本文以Maven項目為例,介紹使用Druid連接池連接數(shù)據(jù)庫前的準備工作。
Maven是一個Java項目管理工具,其為開發(fā)者提供了一套標準化的Java項目構(gòu)建流程與依賴管理機制。使用Maven創(chuàng)建的Java項目帶有標準化的目錄結(jié)構(gòu),其中pom.xml
為項目描述文件,src/main/java
目錄存放項目的Java源代碼,src/main/resources
目錄存放項目資源文件。
安裝Druid:您需要在
pom.xml
文件的dependencies
中添加以下依賴項安裝Druid,Druid連接池版本建議選擇1.2.13及以上。<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.19</version> </dependency>
通過
druid-spring-boot-starter
使用連接池Druid時,為了簡化依賴關(guān)系,便于后續(xù)Druid版本的更新維護,您需要在pom.xml
文件的dependencies
中先排除其依賴的Druid組件,再顯式依賴Druid組件,如下所示。<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>
使用Druid連接數(shù)據(jù)庫
配置連接池參數(shù):您需要在項目的
src/main/resources
目錄中新建druid.properties
文件,并在文件中添加以下內(nèi)容為連接池配置相關(guān)參數(shù),參數(shù)說明詳情請參見Druid連接池常見參數(shù)配置。說明RDS MySQL數(shù)據(jù)庫連接地址和端口的獲取方法,請參見查看和管理實例連接地址和端口。
# 驅(qū)動類名,無需替換 driverClassName=com.mysql.jdbc.Driver # url、username、password、database需要替換為業(yè)務(wù)實際的內(nèi)容 url=jdbc:mysql://rm-bp**************.mysql.rds.aliyuncs.com:3306/database username=**** password=**** # 初始化時創(chuàng)建的連接數(shù) initialSize=20 # 最小空閑連接數(shù) minIdle=20 # 連接池最大連接數(shù) maxActive=100 # 一條物理連接的存活時間 phyTimeoutMillis=3600000 # 獲取連接最大等待時間,如果連接池中沒有可用連接且已達到最大連接數(shù),則應(yīng)用獲取連接的請求將被阻塞,最多等待maxWait(毫秒),建議保持不變 maxWait=5000 # 連接超時時間,表示數(shù)據(jù)庫驅(qū)動和數(shù)據(jù)庫服務(wù)器之間建立TCP連接的超時時間,單位毫秒 connectTimeout=20000 # Socket超時時間,表示通過TCP連接發(fā)送數(shù)據(jù)(執(zhí)行的sql)后,等待響應(yīng)的超時時間,單位毫秒 socketTimeout=60000 # 連接驗證配置項,建議保持不變 testWhileIdle=true testOnBorrow=false testOnReturn=false # PreparedStatement緩存配置項,此處配置為true表示打開緩存,建議保持不變 poolPreparedStatements=true maxPoolPreparedStatementPerConnectionSize=100
使用連接池訪問數(shù)據(jù)庫:您需要在
src/main/java
目錄存放的源代碼文件中導入相關(guān)依賴,構(gòu)建DruidPoolDemo
類,通過連接池Druid獲取JDBC的連接信息并訪問MySQL數(shù)據(jù)庫。// 導入相關(guān)依賴 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"; // 加載參數(shù) 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(); } } /* 后續(xù)數(shù)據(jù)庫操作(見后文) 創(chuàng)建表: public void createTable() 插入數(shù)據(jù):public void insertData() 查詢數(shù)據(jù):public void selectData() 刪除數(shù)據(jù):public void deleteData() */ }
連接池常見參數(shù)配置
在使用Druid連接數(shù)據(jù)庫時,建議您根據(jù)下述內(nèi)容為連接池設(shè)置合適的參數(shù),使數(shù)據(jù)庫的運行更穩(wěn)定高效。
為了最大程度地避免潛在的風險和不確定性,在將新的參數(shù)值用于生產(chǎn)環(huán)境前,建議您至少進行一輪完整的功能測試和性能測試,以確保系統(tǒng)穩(wěn)定性和可靠性。
推薦配置的參數(shù)
推薦您在使用Druid連接池時設(shè)置以下參數(shù),降低數(shù)據(jù)庫運行風險。
參數(shù)名 | 含義 | 默認值 | 推薦值 | 說明 |
initialSize | 連接池初始化時創(chuàng)建的連接數(shù)。 | 0 | 20~80 |
|
minIdle | 最小空閑連接數(shù)。 | 0 | 20~80 |
|
maxActive | 連接池最大連接數(shù)。 | 8 | 100 |
|
phyTimeoutMillis | 一條物理連接的存活時間(毫秒)。 | -1 | 3600000~28800000 |
|
maxWait | 獲取連接時的最大等待時間(毫秒)。 | -1 | 5000 |
|
connectTimeout | 連接超時的時間(毫秒)。 | 10000 | 3000 |
|
socketTimeout | socket的超時時間(毫秒)。 | 10000 | 10000~60000 |
|
testWhileIdle | 是否開啟空閑連接的檢測。 | false | true | 建議設(shè)置為 |
可選擇配置的參數(shù)
使用Druid連接池時,您可以選擇性地配置以下參數(shù),提升數(shù)據(jù)庫性能。
參數(shù)名 | 含義 | 默認值 | 推薦值 | 說明 |
poolPreparedStatements | 是否緩存PreparedStatement對象。 | true | true |
|
maxPoolPreparedStatementPerConnectionSize | 每個連接緩存PreparedStatement對象的最大數(shù)量。 | 10 | 100 |
|
保持默認配置的參數(shù)
對于以下常見的連接池參數(shù),您可以選擇直接使用默認配置或根據(jù)自身需求調(diào)整參數(shù)。
參數(shù)名 | 含義 | 默認值 | 推薦值 | 說明 |
failFast | 用于控制在獲取連接出現(xiàn)錯誤時的行為。 | false | false |
|
timeBetweenEvictionRunsMillis | 檢測空閑連接的時間間隔(毫秒)。 | 60000 | 60000 |
|
后續(xù)數(shù)據(jù)庫操作
您可以在DruidPoolDemo
類中添加自定義函數(shù),滿足對數(shù)據(jù)庫操作的需求,本文以創(chuàng)建數(shù)據(jù)表、插入數(shù)據(jù)、查詢數(shù)據(jù)、刪除數(shù)據(jù)為例。
創(chuàng)建表
String tableName = "sql_table_test";
public void createTable() throws SQLException {
// 創(chuàng)建表
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);
}
}
}
插入數(shù)據(jù)
String tableName = "sql_table_test";
public void insertData(){
// 插入數(shù)據(jù)
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();
}
}
查詢數(shù)據(jù)
String tableName = "sql_table_test";
public void selectData() throws SQLException {
// 查詢數(shù)據(jù)
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);
}
}
}
}
刪除數(shù)據(jù)
String tableName = "sql_table_test";
public void deleteData(){
// 刪除數(shù)據(jù)
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();
}
}
相關(guān)文檔
Python連接池:使用Python連接池DBUtils連接數(shù)據(jù)庫
Go驅(qū)動包:使用Go驅(qū)動包Go-MySQL-Driver連接數(shù)據(jù)庫
RDS MySQL數(shù)據(jù)庫代理中的連接池功能:RDS MySQL設(shè)置連接池