連接池原理解讀,各個連接池對比

1.JDBC規範的實現

JDBC(Java DataBase Connectivity)是Java和數據庫之間的一個橋樑,是一個規範而不是一個實現,能夠執行SQL語句。它由一組用Java語言編寫的類和接口組成。各種不同類型的數據庫都有相應的實現。本文以Mysql實現爲例。

1.1.JDBC編程模型

1.裝載相應數據庫的JDBC驅動並進行初始化;
2.建立JDBC和數據庫之間的Connection連接;
3.創建Statement或者PreparedStatement接口;
4.執行SQL語句;
5.處理和顯示結果;
6.釋放資源
在這裏插入圖片描述

1.2.MySql對JDBC的實現

在我們學習JDBC的時候,我們就開始寫代碼連接數據庫。那時候我們會寫如下代碼:

	@Test
	public void testDB() throws Exception {
		try {
			String dbUrl = "";
			String userName = "";
			String passWord = "";
			Class.forName("com.mysql.jdbc.Driver");
			Connection connection = DriverManager.getConnection(dbUrl,userName,passWord);
			Statement statement = connection.createStatement();
			String sql = "";
			statement.execute(sql);
			statement.close();
			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

寫着寫着,我們就會發現,這樣寫代碼太繁瑣了,每次我明明只是關注寫String sql = “”;但是卻要重複的編寫加載驅動,獲取連接,關閉連接等重複代碼。於是我們可能會編寫一個工具類,來幫我們完成這堆重複代碼,並且考慮線程等問題。但是這樣僅僅只是減少了我們的代碼量,其背後網絡資源、數據庫的性能消耗更加值得我們關注。

1.3.傳統JDBC帶來的問題

1.3.1.網絡資源問題

站在網絡的角度上,當我們在傳統的JDBC中,執行一個SQL語句時,我們需要如下幾個階段:
1.建立網絡TCP
2.MySql連接認證
3.sql語句執行
4.MySql關閉連接
5.關閉TCP
流程示意圖如下
在這裏插入圖片描述
通過流程示意圖,我們發現,我們雖然僅僅只是編寫SQL操作數據,卻存在諸多網絡操作。那麼這個時候,性能肯定會受到網絡資源的影響。假設已經有人幫我們建立了網絡TCP,認證了數據庫,而我們也不需要關心如何關閉連接,關閉網絡。那對於我們操作數據庫來說,性能是不是就得到了很大的提升?

1.3.2.併發訪問資源問題

相信大家一定有這樣的經歷,去銀行或者其他櫃檯辦理業務的時候,如果辦理業務的人數量小於正常辦理業務的窗口,這時候是有空閒的窗口,我們不需要等待的。但是來辦理業務的人數量大於窗口服務數量,這時候就需要取號排隊等待了,隨着辦理業務的人員越來越多,最終等待的人原來越多,如果中間在遇到個別幾個窗口不服務,那等待就更嚴重了。
數據庫也一樣,假設客戶端發起了很多請求,但是服務端不能及時處理完這些請求,或者說,當請求數大於可用的處理數(數據庫最大連接數),那就存在一些應用程序無法訪問到數據庫。
在這裏插入圖片描述

1.3.3.需要解決的問題

減少網絡資源的消耗
控制客戶端訪問服務的請求數量

2.連接池

2.1.什麼是數據庫連接池

數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重複使用一個現有的數據庫連接,而不是再重新建立一個。

2.2.連接池原理

2.2.1.連接池的建立

連接池的工作原理主要由三部分組成:連接池的建立、連接池中連接的使用管理、連接池的關閉。
第一、連接池的建立。一般在系統初始化時,連接池會根據系統配置建立,並在池中創建了幾個連接對象,以便使用時能從連接池中獲取。連接池中的連接不能隨意創建和關閉,這樣避免了連接隨意建立和關閉造成的系統開銷。

2.2.2.連接的管理

當客戶請求數據庫連接時,首先查看連接池中是否有空閒連接,如果存在空閒連接,則將連接分配給客戶使用;
如果沒有空閒連接,則查看當前所開的連接數是否已經達到最大連接數,如果沒達到就重新創建一個連接給請求的客戶;
如果達到就按設定的最大等待時間進行等待,如果超出最大等待時間,則拋出異常給客戶。

2.2.3.連接的關閉

當應用程序退出(服務器關閉,宕機等情況)時,關閉連接池中所有的連接,釋放連接池相關的資源。
程序調用close,並不是真正的關閉連接,而是將連接歸還到連接池。

2.3.連接池的作用

2.3.1.資源重用

由於數據庫連接得到重用,避免了頻繁創建、釋放連接引起的大量性能開銷。在減少系統消耗的基礎上,增進了系統環境的平穩性(減少內存碎片以級數據庫臨時進程、線程的數量)

2.3.2.提升系統響應速度

數據庫連接池在初始化過程中,往往已經創建了若干數據庫連接置於池內備用。此時連接池的初始化操作均已完成。對於業務請求處理而言,直接利用現有可用連接,避免了數據庫連接初始化和釋放過程的時間開銷,從而縮減了系統整體響應時間。

2.3.3.統一管理連接

數據庫連接池負責創建、分配、管理和釋放連接,能避免數據庫連接泄露,並且檢測有問題的連接。

3.連接池的發展

從連接池的發展來說,可以把連接池劃分爲第一、二代連接池。
第一代連接池:一般來講採用單線程同步的架構設計都屬於第一代連接池。
第二代連接池:採用多線程異步架構
先上圖。
在這裏插入圖片描述

3.1.C3P0

一句話概括C3P0,死翹翹
國外是什麼情況,這個博主不知道,不過國內C3P0確實已經被打入冷宮了,在很長一段時間內,它一直是Java領域內數據庫連接池的代名詞。就連當年牛逼轟轟的Hibernate(有幸在大三自學,現在畢業三年多了,但是從未參與過hibernate的項目)將其作爲內置的數據庫連接池。只不過後浪推前浪,在今天Hibernate一樣死翹翹了。導致C3P0死翹翹的原因在於他的性能以及代碼複雜度。哪怕在C3P0使用量最爲巔峯的時期,其性能也是同期產品性能最墊底的。可能就是代碼太過於複雜,導致官方於2015年放棄更新維護。本身就是性能最差的第一代連接池,在今天被打入冷宮實屬正常。

3.2.DBCP

一句話概括DBCP,差點鹹魚翻身
DBCP(DataBase Connection Pool)屬於Apache頂級項目Commons中的核心子項目。但DBCP並不是獨立實現連接池功能的,它內部依賴於Commons中的另一個子項目Pool,連接池最核心的“池”,就是由Pool組件提供的,因此,DBCP的性能實際上就是Pool的性能。

換句話說,DBCP的命脈在Pool的手裏

終於在tomcat 7.0版本中,tomcat重新設計開發出了一套連接池(Tomcat JDBC Pool)並且於13年9月發佈了Commons-Pool 2.0。命脈已經更新的DBCP終於在14年2月份發佈了DBCP2.0。但是,畢竟由於長時間沒有更新突破的DBCP,已經被人放棄了。

3.3.Druid

阿里巴巴出品,藉助於阿里這個平臺的號召力,產品一經發布就贏得了大批用戶的擁躉,從用戶使用的反饋來看,Druid也確實沒讓用戶失望。相較於其他產品,Druid另一個比較大的優勢,就是中文文檔比較全面。
Druid 相對於其他數據庫連接池的優點
強大的監控特性,通過Druid提供的監控功能,可以清楚知道連接池和SQL的工作情況。
優點1. 監控SQL的執行時間、ResultSet持有時間、返回行數、更新行數、錯誤次數、錯誤堆棧信息;

優點2. SQL執行的耗時區間分佈。什麼是耗時區間分佈呢?比如說,某個SQL執行了1000次,其中01毫秒區間50次,110毫秒800次,10100毫秒100次,1001000毫秒30次,1~10秒15次,10秒以上5次。通過耗時區間分佈,能夠非常清楚知道SQL的執行耗時情況;

優點3. 監控連接池的物理連接創建和銷燬次數、邏輯連接的申請和關閉次數、非空等待次數、PSCache命中率等。

優點4.Druid提供了Filter-Chain模式的擴展API,可以自己編寫Filter攔截JDBC中的任何方法,可以在上面做任何事情,比如說性能監控、SQL審計、用戶名密碼加密、日誌等等。
Druid集合了開源和商業數據庫連接池的優秀特性,並結合阿里巴巴大規模苛刻生產環境的使用經驗進行優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章