池化技術-數據庫連接池

概述

什麼是連接池
1)先講一下“池”, 池(Pool)技術在一定程度上可以明顯優化服務器應用程序的性能,提高程序執行效率和降低系統資源開銷。這裏所說的池是一種廣義上的池,比如數據庫連接池、線程池、內存池、對象池等。其中,對象池可以看成保存對象的容器,在進程初始化時創建一定數量的對象。需要時直接從池中取出一個空閒對象,用完後並不直接釋放掉對象,而是再放到對象池中以方便下一次對象請求可以直接複用。其他幾種池的設計思想也是如此,池技術的優勢是,可以消除對象創建所帶來的延遲,從而提高系統的性能。

爲什麼要使用連接池
 數據庫連接是一種關鍵的有限的昂貴的資源,這一點在多用戶的網頁應用程序中體現得尤爲突出。  一個數據庫連接對象均對應一個物理數據庫連接,每次操作都打開一個物理連接,使用完都關閉連接,這樣造成系統的 性能低下。 數據庫連接池的解決方案是在應用程序啓動時建立足夠的數據庫連接,並講這些連接組成一個連接池(簡單說:在一個“池”裏放了好多半成品的數據庫聯接對象),由應用程序動態地對池中的連接進行申請、使用和釋放。對於多於連接池中連接數的併發請求,應該在請求隊列中排隊等待。並且應用程序可以根據池中連接的使用率,動態增加或減少池中的連接數。 連接池技術儘可能多地重用了消耗內存地資源,大大節省了內存,提高了服務器地服務效率,能夠支持更多的客戶服務。通過使用連接池,將大大提高程序運行效率,同時,我們可以通過其自身的管理機制來監視數據庫連接的數量、使用情況等。

不使用數據庫連接池的步驟:

  1. TCP建立連接的三次握手
  2. MySQL認證的三次握手
  3. 真正的SQL執行
  4. MySQL的關閉
  5. TCP的四次握手關閉

可以看到,爲了執行一條SQL,卻多了非常多我們不關心的網絡交互。

優點:
實現簡單
缺點:
網絡IO較多
數據庫的負載較高
響應時間較長及QPS較低
應用頻繁的創建連接和關閉連接,導致臨時對象較多,GC頻繁
在關閉連接後,會出現大量TIME_WAIT 的TCP狀態(在2個MSL之後關閉)。

使用連接池步驟:

系統初始化時創建連接池,程序操作數據庫時從連接池中獲取空閒連接,程序使用完畢將連接歸還到連接池中,系統退出時,斷開所有數據庫連接並釋放內存資源。

優點:

  1. 較少了網絡開銷
  2. 系統的性能會有一個實質的提升
  3. 沒了麻煩的TIME_WAIT狀態

到這兒,我想到了IO多路複用技術,那爲什麼選擇了創建一定數量的數據庫連接形成數據庫連接池,而不是使用nio來處理多個數據庫連接呢?有興趣的可以看一下這片文章  https://www.zhihu.com/question/23084473?sort=created

主流的數據庫連接池對比:

常用的主流開源數據庫連接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等

我們再看一組有HikariCP的:

性能方面 hikari>druid>tomcat-jdbc>dbcp>c3p0 

性能無敵的HikariCP

HikariCP號稱“性能殺手”(It’s Faster),springboot 2.0以上默認使用該連接池。

那它是怎麼做到如此強勁的呢?官網給出的說明如下:

字節碼精簡:優化代碼,直到編譯後的字節碼最少,這樣,CPU緩存可以加載更多的程序代碼;
優化代理和攔截器:減少代碼,例如HikariCP的Statement proxy只有100行代碼;
自定義數組類型(FastStatementList)代替ArrayList:避免每次get()調用都要進行range check,避免調用remove()時的從頭到尾的掃描;
自定義集合類型(ConcurrentBag):提高併發讀寫的效率;
其他缺陷的優化,比如對於耗時超過一個CPU時間片的方法調用的研究(但沒說具體怎麼優化)。
可以看到,上述這幾點優化,和現在能找到的資料來看,HakariCP在性能上的優勢應該是得到共識的,再加上它自身小巧的身形,在當前的“雲時代、微服務”的背景下,HakariCP一定會得到更多人的青睞。

HikariCP源碼解析:https://www.cnblogs.com/hama1993/p/11421579.html

HikariCP地址:https://github.com/brettwooldridge/HikariCP

功能全面的Druid

相較於其他產品,Druid另一個比較大的優勢,就是中文文檔比較全面(畢竟是國人的項目麼),在github的wiki頁面,列舉了日常使用中可能遇到的問題,對一個新用戶來講,上面提供的內容已經足夠指導它完成產品的配置和使用了。

 現在項目開發中,我還是比較傾向於使用Durid,它不僅僅是一個數據庫連接池,它還包含一個ProxyDriver,一系列內置的JDBC組件庫,一個SQL Parser,所以我們項目目前用的也是這個連接池。

Druid 相對於其他數據庫連接池的優點
強大的監控特性,通過Druid提供的監控功能,可以清楚知道連接池和SQL的工作情況。
a. 監控SQL的執行時間、ResultSet持有時間、返回行數、更新行數、錯誤次數、錯誤堆棧信息;

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

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

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

Druid源碼解析:https://www.cnblogs.com/hama1993/p/11421576.html

Druid地址:https://github.com/alibaba/druid

數據庫連接池的工作原理:

  • 連接池的建立:一般在系統初始化時,連接池會根據系統配置建立,並在池中創建了幾個連接對象,以便使用時能從連接池中獲取。連接池中的連接不能隨意創建和關閉,這樣避免了連接隨意建立和關閉造成的系統開銷。Java中提供了很多容器類可以方便的構建連接池,例如Vector、Stack等。
  • 連接池的管理。連接池管理策略是連接池機制的核心,連接池內連接的分配和釋放對系統的性能有很大的影響。其管理策略是:當客戶請求數據庫連接時,首先查看連接池中是否有空閒連接,如果存在空閒連接,則將連接分配給客戶使用;如果沒有空閒連接,則查看當前所開的連接數是否已經達到最大連接數,如果沒達到就重新創建一個連接給請求的客戶;如果達到就按設定的最大等待時間進行等待,如果超出最大等待時間,則拋出異常給客戶。當客戶釋放數據庫連接時,先判斷該連接的引用次數是否超過了規定值,如果超過就從連接池中刪除該連接,否則保留爲其他客戶服務。 該策略保證了數據庫連接的有效複用,避免頻繁的建立、釋放連接所帶來的系統資源開銷。
  • 連接池的關閉:當應用程序退出時,關閉連接池中所有的連接,釋放連接池相關的資源,以便連接可以返回池中重複利用。我們可以通過Connection對象的Close或Dispose方法,也可以通過C#的using語句來關閉連接。該過程正好與創建相反。

 

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