本文由簡體中文內容自動轉碼而成。阿里雲不保證此自動轉碼的準確性、完整性及時效性。本文内容請以簡體中文版本為準。

使用Java串連池Druid串連資料庫

更新時間:2024-10-25 19:18

如果您的應用側主要使用Java語言,且資料庫連接建立頻繁(例如短串連情境)或串連數量較大(大於MySQL資料庫的串連數限制),您可以使用Java串連池Druid串連資料庫,降低串連建立頻率以減少資料庫主線程的開銷。

前提條件

  • 應用伺服器已安裝Java環境且JDK版本在1.8及以上。

  • 已將伺服器IP地址添加至RDS執行個體白名單中,詳情請參見設定IP白名單

    說明

    若您的應用程式部署在阿里雲ECS伺服器上,且ECS與RDS已實現內網互連(ECS與RDS執行個體的地區、VPC均相同),則無需設定IP白名單。

準備工作

本文以Maven專案為例,介紹使用Druid串連池串連資料庫前的準備工作。

說明

Maven是一個Java專案管理工具,其為開發人員提供了一套標準化的Java專案構建流程與依賴管理機制。使用Maven建立的Java專案帶有標準化的目錄結構,其中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時,為了簡化依賴關係,便於後續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串連資料庫

  1. 配置串連池參數:您需要在專案的src/main/resources目錄中建立druid.properties檔案,並在檔案中添加以下內容為串連池配置相關參數,參數說明詳情請參見Druid串連池常見參數配置

    說明

    RDS MySQL資料庫連接地址和連接埠的擷取方法,請參見查看和管理執行個體串連地址和連接埠

    # 驅動類名,無需替換
    driverClassName=com.mysql.jdbc.Driver
    
    # url、username、password、database需要替換為業務實際的內容
    url=jdbc:mysql://rm-bp**************.mysql.rds.aliyuncs.com:3306/database
    username=****
    password=****
    
    # 初始化時建立的串連數
    initialSize=20
    # 最小空閑串連數
    minIdle=20
    # 串連池最大串連數
    maxActive=100
    # 一條物理串連的存活時間
    phyTimeoutMillis=3600000
    # 擷取串連最大等待時間,如果串連池中沒有可用串連且已達到最大串連數,則應用擷取串連的請求將被阻塞,最多等待maxWait(毫秒),建議保持不變
    maxWait=5000
    # 連線逾時時間,表示資料庫驅動和資料庫伺服器之間建立TCP串連的逾時時間,單位毫秒
    connectTimeout=20000
    # Socket逾時時間,表示通過TCP串連發送資料(執行的sql)後,等待響應的逾時時間,單位毫秒
    socketTimeout=60000
    
    # 串連驗證配置項,建議保持不變
    testWhileIdle=true
    testOnBorrow=false
    testOnReturn=false
    
    # PreparedStatement緩衝配置項,此處配置為true表示開啟緩衝,建議保持不變
    poolPreparedStatements=true
    maxPoolPreparedStatementPerConnectionSize=100
  2. 使用串連池訪問資料庫:您需要在src/main/java目錄存放的原始碼檔案中匯入相關依賴,構建DruidPoolDemo類,通過串連池Druid擷取JDBC的串連資訊並訪問MySQL資料庫。

    // 匯入相關依賴
    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";
        // 載入參數
        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();
            }
        }
        /* 
          後續資料庫操作(見後文)
          建立表:  public void createTable()
          插入資料:public void insertData()
          查詢資料:public void selectData()
          刪除資料:public void deleteData()
        */
    }

串連池常見參數配置

在使用Druid串連資料庫時,建議您根據下述內容為串連池設定合適的參數,使資料庫的運行更穩定高效。

重要

為了最大程度地避免潛在的風險和不確定性,在將新的參數值用於生產環境前,建議您至少進行一輪完整的功能測試和效能測試,以確保系統穩定性和可靠性。

推薦配置的參數
可選擇配置的參數
保持預設配置的參數

推薦您在使用Druid串連池時設定以下參數,降低資料庫運行風險。

參數名

含義

預設值

推薦值

說明

initialSize

串連池初始化時建立的串連數。

0

20~80

  • 設定合理的initialSize,應用啟動後可以立即處理並發需求。

  • 建議設定為平均並發串連數的60%至80%。

minIdle

最小空閑串連數。

0

20~80

  • 適當配置minIdle可以預留一定數量的串連,快速處理突發的資料庫請求。

  • 建議參考initialSize的參數設定或設定為JVM在無壓力時保留的串連數。

  • 活躍串連數與此參數無關,其受maxActive參數控制。

maxActive

串連池最大串連數。

8

100

  • 該參數值需根據應用程式的實際需求及資料庫的處理能力決定。

  • 建議設定為資料庫能同時處理的最大串連數,或略大於預計峰值並發量,預留一定的串連應對突發流量。

phyTimeoutMillis

一條物理串連的存活時間(毫秒)。

-1

3600000~28800000

  • 預設值-1表示串連永久存在。

  • 參數值需要根據實際情況決定,設定該值是為了防止空閑串連長時間存在,浪費資源。

maxWait

擷取串連時的最大等待時間(毫秒)。

-1

5000

  • 如果串連池中沒有可用串連且已經達到最大串連數,則應用擷取串連的請求將被阻塞,最多等待該參數設定的時間。

  • 預設值-1表示一直等待,0表示不等待(不建議設定為-10)。

  • 正常情況下,擷取資料庫連接的等待時間為10至30毫秒,建議按實際需求或推薦值設定參數。

connectTimeout

連線逾時的時間(毫秒)。

10000

3000

  • 資料庫驅動與資料庫伺服器建立TCP串連的逾時時間。

  • 建議設定為1-10秒之間,取決於網路品質高低,以及應用端與服務端的距離。

socketTimeout

socket的逾時時間(毫秒)。

10000

10000~60000

  • 通過TCP串連發送資料(待執行的SQL命令)後,等待響應的逾時時間。

  • 該參數值不宜過短,針對SQL執行時間明顯過長而導致逾時的問題,應該首先檢查SQL或者資料庫本身,而不是優先調整該參數。

testWhileIdle

是否開啟空閑串連的檢測。

false

true

建議設定為true,串連池會定期檢查空閑串連的狀態。

使用Druid串連池時,您可以選擇性地配置以下參數,提升資料庫效能。

參數名

含義

預設值

推薦值

說明

poolPreparedStatements

是否緩衝PreparedStatement對象。

true

true

  • 開啟後,在重複執行相同SQL語句時,可以減少編譯SQL語句的次數,提高效能。

  • 開啟後,可以有效防止SQL注入攻擊,增強安全性。

  • 如果業務SQL變化較大或業務有很多大欄位,設定該參數會導致大量的JVM記憶體消耗,也會導致較多的資料庫服務端記憶體消耗。

maxPoolPreparedStatementPerConnectionSize

每個串連緩衝PreparedStatement對象的最大數量。

10

100

  • 如果開啟了緩衝PreparedStatement對象,串連池會限制每個串連緩衝的最大數量。

  • 對於執行大量重複SQL語句的應用,可以將該參數值調高,但設定過高會導致記憶體浪費。

對於以下常見的串連池參數,您可以選擇直接使用預設配置或根據自身需求調整參數。

參數名

含義

預設值

推薦值

說明

failFast

用於控制在擷取串連出現錯誤時的行為。

false

false

  • 一般情況下,保持預設設定不變。

  • 在錯誤敏感、擷取串連頻繁失敗的情境下,可以將該參數設定為true

    • 快速響應錯誤:如果串連池已滿或連線逾時等,串連擷取操作會在出現錯誤時立即失敗,不會進行重試或等待。

    • 避免長時間等待:在高並發的情境下,可以與maxWaitThreadCount參數一起使用,避免長時間等待串連擷取。

timeBetweenEvictionRunsMillis

檢測空閑串連的時間間隔(毫秒)。

60000

60000

  • 串連池會定期(按此參數時間間隔)檢查串連,判斷空閑時間是否超過minEvictableIdleTimeMillis參數設定的最小空閑時間。

  • 建議保持預設參數值不變。如果要修改此值,應當根據具體情況進行調整,以達到最佳的串連池利用率和效能表現。

後續資料庫操作

您可以在DruidPoolDemo類中添加自訂函數,滿足對資料庫操作的需求,本文以建立資料表、插入資料、查詢資料、刪除資料為例。

建立表
插入資料
查詢資料
刪除資料
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);
        }
    }
}
String tableName = "sql_table_test";
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();
    }
}
String tableName = "sql_table_test";
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);
            }
        }
    }
}
String tableName = "sql_table_test";
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();
    }
}

相關文檔

  • 本頁導讀 (1, M)
  • 前提條件
  • 準備工作
  • 使用Druid串連資料庫
  • 串連池常見參數配置
  • 後續資料庫操作
  • 相關文檔
文檔反饋
phone 聯絡我們

立即和Alibaba Cloud在線服務人員進行交談,獲取您想了解的產品信息以及最新折扣。

alicare alicarealicarealicare