淺析資料庫連接池(二),淺析資料庫連接池

來源:互聯網
上載者:User

淺析資料庫連接池(二),淺析資料庫連接池

上一篇部落格,主要是簡單的介紹了普通資料庫連接的過程以及耗費的資源,並且簡單的談了下串連池,這篇我們主要來看看資料庫連接池的使用以及它最優的配置。

總目錄:
-1.資料庫連接過程是怎樣的?
-2.串連所佔用的資源有哪些?
-3.串連池簡介
-4.串連池的使用
-5.最優串連池配置選擇

今天主要看看4和5。

4.串連池的使用

這裡我使用的是c3p0資料庫連接池
簡單的介紹一下c3p0:C3P0是一個開源的JDBC串連池,它實現了資料來源和JNDI綁定,支援JDBC3規範和JDBC2的標準擴充。目前使用它的開源項目有Hibernate,Spring等。

串連池的種類也有很多,而且每種也有不同的適用情境,所以選擇適合自己的串連池也是一方面~

先放不使用串連池和使用串連池的資料對比。
迴圈串連10次,圖片為測試的第10組資料。

不使用串連池

使用串連池
紅色為串連池部分配置資訊

從圖片我們可以明顯的看出,串連池的速度要快於普通串連很多,這裡很多不是指的二者差多少毫秒,而是倍數的差別。

java串連池代碼:
import com.mchange.v2.c3p0.ComboPooledDataSource;import java.awt.color.ProfileDataException;import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ResourceBundle;/** * Created by wwh on 15-6-10. */public class DBPollClass {    private static DBPollClass dbPoll;    private ComboPooledDataSource dbSource;    //靜態代碼塊,一開始我們就執行建構函式載入配置資訊    static {        dbPoll = new DBPollClass();    }    public DBPollClass(){        //設定配置資訊        try{            dbSource = new ComboPooledDataSource();            dbSource.setUser("root");            dbSource.setPassword("123456789");            dbSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/XL_db?user=root&password=123456789&useUnicode=true");            dbSource.setDriverClass("com.mysql.jdbc.Driver");            dbSource.setInitialPoolSize(1);            dbSource.setMinPoolSize(2);            dbSource.setMaxPoolSize(10);            dbSource.setMaxStatements(50);            dbSource.setMaxIdleTime(60);        }catch (PropertyVetoException e){            throw new RuntimeException(e);        }    }    //獲得串連    public final static DBPollClass getInstance(){        return dbPoll;    }    public final Connection getConnection(){        try{            return dbSource.getConnection();        }catch (SQLException e){            throw new RuntimeException("無法擷取串連", e);        }    }    public static void main(String[] args) throws SQLException {        for(int i = 0; i < 10; i++) {            long begintime = System.currentTimeMillis();            Connection con = null;            try {                //取得空閑串連                con = dbPoll.getInstance().getConnection();                //執行sql語句並返回查詢結果                //ResultSet rs = con.createStatement().executeQuery("SELECT * from UserInfo");                //使用PreparedStatement而不使用Statement                PreparedStatement pst = con.prepareStatement("SELECT * from UserInfo");                ResultSet rs = pst.executeQuery();                //輸出查詢結果                while (rs.next()) {                    System.out.println(rs.getObject(1) + " " + rs.getObject(2) + " " + rs.getObject(3) + " " + rs.getObject(4));                }            } catch (Exception e) {                e.printStackTrace();            } finally {                if (con != null) {                    //歸還空閑串連                    con.close();                }            }            long endtime = System.currentTimeMillis();            System.out.println((i+1) + " time is:" + (endtime-begintime));        }    }}

從代碼我們可以和清晰的看出串連池的使用是非常簡單的,代碼中我將串連池的配置等資訊寫到了建構函式中,其實現實中使用我們一般寫在c3p0-config.xml,資料庫連接池的設定檔中,然後放到src目錄下即可。
串連池的使用步驟和普通的JDBC串連資料庫基本一樣。參數也類似
只不過部分含義不同,串連池的connection,並不是建立串連,而是從資料庫連接池中間找出一個閒置串連,con.close()也不是中斷連線,而是歸還給串連池。
還有注意我們不僅僅要歸還connection資源,還要歸還Preparedstatement和ResultSet的資源
我們也需要養成良好的習慣使用Preparedstatement而不是statement,因為Preparedstatement裡麵包含了部分已經編譯好的sql語句,可以提高執行速度。

5.最優串連池配置選擇

使用和使用好兩個詞是截然不同的,我們的目的不僅僅是使用線程池或者資料庫連接池,而是通過使用它們來發揮伺服器最大威力以及效率達到最優。
這就要我們根據自己伺服器配置資訊來選擇參數了~。
先看看代碼中我們設定了哪些參數。

設定初始化串連池大小
dbSource.setInitialPoolSize(1);

設定串連池內最小串連數
dbSource.setMinPoolSize(2);

設定串連池內最大串連數
dbSource.setMaxPoolSize(10);

用來控制Preparedstatement的數量
dbSource.setMaxStatements(50);

最大空閑時間,60秒內未使用串連則被丟取,設定為0則永不丟棄
dbSource.setMaxIdleTime(60);
以上為常用和關鍵的參數。

關於最關鍵的參數設定
1.最小串連數
串連池一直保持的資料庫連接。最小串連數的大小我們要根據實際的使用方式不斷的測試來決定,如果設定大了就會有許多閒置串連,浪費了資源。

2.最大串連數
串連池的串連上限,一般當串連值大於最小串連數時,串連池就會建立新的connection來接受串連,我們設定的逾時時間就是針對新建立的串連的,當使用完最小串連數外的串連時,它們不會被立即釋放,而是停留MaxIdleTime時間,如果在MaxIdleTime時間沒有再次被串連,則釋放。如果超過最大串連數,那麼新到的串連會被加入到等待隊列中。

3.最大空閑時間MaxIdleTime,這個要根據實際情況來調整設定了。

如果最小串連數和最大串連數相差很大,那麼最先到的串連最獲利,連線速度非常快,後到的會稍微慢點,因為要建立串連。

我們一般設定池的大小時,比如線程池,首先要確定是CPU密集型還是IO密集型,如果是CPU密集型,那麼我們如果線程池設定應該和CPU核心數幾乎一致,因為此時大量的計算,如果線程數量設定過大,那麼線程切換消耗的時間就是主要花費,如果是IO密集型,那麼線程數量要大於CPU數量,因為線程可能阻塞在IO處,所以阻塞時要切換其他線程繼續執行,效率會高。

那麼訪問資料庫是IO密集型的,因為內部也是建立單獨的線程來串連,所以類似線程池,線程池IO密集型線程數計算公式為:
線程數 = CPU核心數 / (1-阻塞係數),阻塞係數也應該根據我們具體情況來分析。
一般線程數為核心數的幾倍。

我就簡單的介紹到這裡,上面所說也是根據自己現有的知識和查詢的資料來描述的,並不一定全部正確,希望大家帶著審視的眼光來看,如果哪部分錯了,還望指出,謝謝~

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.