概述
數據庫連接池是負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個。那么其中的運行機制又是怎樣的呢?今天主要介紹一下數據庫連接池原理和常用的連接池。
01
為什么要使用連接池
數據庫連接是一種關鍵的有限的昂貴的資源,這一點在多用戶的網頁應用程序中體現得尤為突出。 一個數據庫連接對象均對應一個物理數據庫連接,每次操作都打開一個物理連接,使用完都關閉連接,這樣造成系統的性能低下。
數據庫連接池的解決方案是在應用程序啟動時建立足夠的數據庫連接,并講這些連接組成一個連接池(簡單說:在一個“池”里放了好多半成品的數據庫連接對象),由應用程序動態地對池中的連接進行申請、使用和釋放。對于多于連接池中連接數的并發請求,應該在請求隊列中排隊等待。并且應用程序可以根據池中連接的使用率,動態增加或減少池中的連接數。
連接池技術盡可能多地重用了消耗內存地資源,大大節省了內存,提高了服務器地服務效率,能夠支持更多的客戶服務。通過使用連接池,將大大提高程序運行效率,同時,我們可以通過其自身的管理機制來監視數據庫連接的數量、使用情況等。
02
傳統的連接機制與數據庫連接池運行機制區別
1、不使用連接池流程
下面以訪問MySQL為例,執行一個SQL命令,如果不使用連接池,需要經過哪些流程。
不使用數據庫連接池的步驟:
- TCP建立連接的三次握手
- MySQL認證的三次握手
- 真正的SQL執行
- MySQL的關閉
- TCP的四次握手關閉
可以看到,為了執行一條SQL,卻多了非常多網絡交互。
優點:
- 實現簡單
缺點:
- 網絡IO較多
- 數據庫的負載較高
- 響應時間較長及QPS較低
- 應用頻繁的創建連接和關閉連接,導致臨時對象較多,GC頻繁
- 在關閉連接后,會出現大量TIME_WAIT 的TCP狀態(在2個MSL之后關閉)
2、使用連接池流程
使用數據庫連接池的步驟:
第一次訪問的時候,需要建立連接。 但是之后的訪問,均會復用之前創建的連接,直接執行SQL語句。
優點:
- 較少了網絡開銷
- 系統的性能會有一個實質的提升
- 沒了麻煩的TIME_WAIT狀態
03
數據庫連接池的工作原理
連接池的工作原理主要由三部分組成,分別為
- 連接池的建立
- 連接池中連接的使用管理
- 連接池的關閉
第一、連接池的建立。
一般在系統初始化時,連接池會根據系統配置建立,并在池中創建了幾個連接對象,以便使用時能從連接池中獲取。連接池中的連接不能隨意創建和關閉,這樣避免了連接隨意建立和關閉造成的系統開銷。
JAVA中提供了很多容器類可以方便的構建連接池,例如Vector、Stack等。
第二、連接池的管理。
連接池管理策略是連接池機制的核心,連接池內連接的分配和釋放對系統的性能有很大的影響。其管理策略是:
當客戶請求數據庫連接時,首先查看連接池中是否有空閑連接,如果存在空閑連接,則將連接分配給客戶使用;如果沒有空閑連接,則查看當前所開的連接數是否已經達到最大連接數,如果沒達到就重新創建一個連接給請求的客戶;如果達到就按設定的最大等待時間進行等待,如果超出最大等待時間,則拋出異常給客戶。
當客戶釋放數據庫連接時,先判斷該連接的引用次數是否超過了規定值,如果超過就從連接池中刪除該連接,否則保留為其他客戶服務。
該策略保證了數據庫連接的有效復用,避免頻繁的建立、釋放連接所帶來的系統資源開銷。
第三、連接池的關閉。
當應用程序退出時,關閉連接池中所有的連接,釋放連接池相關的資源,該過程正好與創建相反。
04
連接池需要注意的點
1、并發問題
為了使連接管理服務具有最大的通用性,必須考慮多線程環境,即并發問題。
這個問題相對比較好解決,因為各個語言自身提供了對并發管理的支持像java,c#等等,使用synchronized(java)lock(C#)關鍵字即可確保線程是同步的。
2、事務處理
我們知道,事務具有原子性,此時要求對數據庫的操作符合“ALL-OR-NOTHING”原則,即對于一組SQL語句要么全做,要么全不做。
我們知道當2個線程共用一個連接Connection對象,而且各自都有自己的事務要處理時候,對于連接池是一個很頭疼的問題,因為即使Connection類提供了相應的事務支持,可是我們仍然不能確定那個數據庫操作是對應那個事務的,這是由于我們有2個線程都在進行事務操作而引起的。
為此我們可以使用每一個事務獨占一個連接來實現,雖然這種方法有點浪費連接池資源但是可以大大降低事務管理的復雜性。
3、連接池的分配與釋放
連接池的分配與釋放,對系統的性能有很大的影響。合理的分配與釋放,可以提高連接的復用度,從而降低建立新連接的開銷,同時還可以加快用戶的訪問速度。
對于連接的管理可使用一個List。即把已經創建的連接都放入List中去統一管理。每當用戶請求一個連接時,系統檢查這個List中有沒有可以分配的連接。如果有就把那個最合適的連接分配給他,如果沒有就拋出一個異常給用戶。
4、連接池的配置與維護
連接池中到底應該放置多少連接,才能使系統的性能最佳?
系統可采取設置最小連接數(minConnection)和最大連接數(maxConnection)等參數來控制連接池中的連接。比方說,最小連接數是系統啟動時連接池所創建的連接數。如果創建過多,則系統啟動就慢,但創建后系統的響應速度會很快;如果創建過少,則系統啟動的很快,響應起來卻慢。這樣,可以在開發時,設置較小的最小連接數,開發起來會快,而在系統實際使用時設置較大的,因為這樣對訪問客戶來說速度會快些。最大連接數是連接池中允許連接的最大數目,具體設置多少,要看系統的訪問量,可通過軟件需求上得到。
如何確保連接池中的最小連接數呢?有動態和靜態兩種策略。動態即每隔一定時間就對連接池進行檢測,如果發現連接數量小于最小連接數,則補充相應數量的新連接,以保證連接池的正常運轉。靜態是發現空閑連接不夠時再去檢查。
總結
時至今日,雖然每個應用(需要RDBMS的)都離不開連接池,但在實際使用的時候,連接池已經可以做到“隱形”了。也就是說在通常情況下,連接池完成項目初始化配置之后,就再不需要再做任何改動了。