最原始的數據庫連接就是我們打開一個連接,使用過后再關閉該鏈接來釋放資源。頻繁的新建打開再關閉連接對jvm和數據庫都有一定的資源負荷,尤其是應用壓力比較大的時候占用過多的資源容易產生性能問題。所以引入數據庫連接池,它的原理就是:先打開一定數量的數據庫連接,當使用的時候分配給使用者,使用結束后返回給連接池,注意返回的時候不需要關閉這些連接,而是準備給下一個調用者分配。這樣就省去了大量的數據庫連接打開和關閉的操作,提升了系統的性能。
最小連接數:應用啟動后就打開的數據庫連接的數量以及后續最小維持的連接數
最大連接數:應用能夠打開的最多的連接數
連接增長數:應用每次打開新連接的個數
最小連接數是連接池一直保持的數據連接。如果應用程序對數據庫連接的使用量不大,將會有大量的數據庫連接資源被浪費掉。
最大連接數是連接池能申請的最大連接數。如果數據連接請求超過此數,后面的數據連接請求將被加入到等待隊列中,這會影響之后的數據庫操作。
如果最小連接數與最大連接數相差太大,那么,最先的連接請求將會獲利,之后超過最小連接數量的連接請求等價于建立一個新的數據庫連接。不過,這些大于最小連接數的數據庫連接在使用完不會馬上被釋放,它將被放到連接池中等待重復使用或是空閑超時后被釋放。
上面的解釋,可以這樣理解:數據庫池連接數量一直保持一個不少于最小連接數的數量,當數量不夠時,數據庫會創建一些連接,直到一個最大連接數,之后連接數據庫就會等待。
假如項目最大并發3000,想知道怎么設置需要
把系統運行起來,你自己寫監聽,統計一段時間內的連接池,然后查看最大的,最小的和平均值,根據這些獲得的參數信息來確定。
舉個例子說明連接池的運作:
假設設置了最小和最大的連接為10,20,那么應用一旦啟動則首先打開10個數據庫連接,但注意此時數據庫連接池的正在使用數字為0--因為你并沒有使用這些連接,而空閑的數量則是10。然后你開始登錄,假設登錄代碼使用了一個連接進行查詢,那么此時數據庫連接池的正在使用數字為1、空閑數為9,這并不需要從數據庫打開連接--因為連接池已經準備好了10個給你留著呢。登錄結束了,當前連接池的連接數量是多少?當然是0,因為那個連接隨著事務的結束已經返還給連接池了。然后同時有11個人在同一秒進行登錄,會發生什么:連接池從數據庫新申請(打開)了一個連接,連同另外的10個一并送出,這個瞬間連接池的使用數是11個,不過沒關系正常情況下過一會兒又會變成0。如果同時有21個人登錄呢?那第21個人就只能等前面的某個人登錄完畢后釋放連接給他。這時連接池開啟了20個數據庫連接--雖然很可能正在使用數量的已經降為0,那么20個連接會一直保持嗎?當然不,連接池會在一定時間內關閉一定量的連接還給數據庫,在這個例子里數字是20-10=10,因為只需要保持最小連接數就好了,而這個時間周期也是連接池里配置的。
DBCP
DBCP是一個依賴Jakarta commons-pool對象池機制的數據庫連接池.DBCP可以直接的在應用程序用使用
可以設置最大和最小連接,連接等待時間等,基本功能都有,此連接池的持續運行的穩定性還是可以,不過速度稍慢,在大并發量的壓力下穩定性有所下降,此外不提供連接池監控
http://homepages.nildram.co.uk/~slink/java/DBPool/
C3P0
C3P0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發布,包括了實現jdbc3和jdbc2擴展規范說明的Connection 和Statement 池的DataSources 對象。
連接池可以設置最大和最小連接,連接等待時間等,基本功能都有,連接池的持續運行的穩定性相當不錯,在大并發量的壓力下穩定性也有一定保證,此外不提供連接池監控。
http://sourceforge.net/projects/c3p0
Proxool
這是一個Java SQL Driver驅動程序,提供了對你選擇的其它類型的驅動程序的連接池封裝。可以非常簡單的移植到現存的代碼中。完全可配置。快速,成熟,健壯。可以透明地為你現存的JDBC驅動程序增加連接池功能。
連接池可以設置最大和最小連接,連接等待時間等,基本功能都有,連接池的持續運行的穩定性有一定問題,有一個優勢--連接池監控
http://proxool.sourceforge.net/
BoneCP
BoneCP是一個快速,開源的數據庫連接池。幫你管理數據連接讓你的應用程序能更快速地訪問數據庫。比C3P0/DBCP連接池快25倍
一種新的數據連接技術,以其效率高,速度 快著稱,連接池可以設置最大和最小連接,連接等待時間等,基本功能都有
http://jolbox.com/about.html
參數說明
DBCP
dataSource: 要連接的 datasource (通常我們不會定義在 server.xml)
defaultAutoCommit: 對于事務是否 autoCommit, 默認值為 true
defaultReadOnly: 對于數據庫是否只能讀取, 默認值為 false
driverClassName:連接數據庫所用的 JDBC Driver Class
maxActive: 可以從對象池中取出的對象最大個數,為0則表示沒有限制,默認為8
maxIdle: 最大等待連接中的數量,設 0 為沒有限制 (對象池中對象最大個數)
minIdle:對象池中對象最小個數
maxWait: 最大等待秒數, 單位為 ms, 超過時間會丟出錯誤信息
password: 登陸數據庫所用的密碼
url: 連接數據庫的 URL
username: 登陸數據庫所用的帳號
validationQuery: 驗證連接是否成功, SQL SELECT 指令至少要返回一行
removeAbandoned: 是否自我中斷, 默認是 false
removeAbandonedTimeout: 幾秒后會自我中斷, removeAbandoned 必須為 true
logAbandoned: 是否記錄中斷事件, 默認為 false
minEvictableIdleTimeMillis:大于0 ,進行連接空閑時間判斷,或為0,對空閑的連接不進行驗證;默認30分鐘
timeBetweenEvictionRunsMillis:失效檢查線程運行時間間隔,如果小于等于0,不會啟動檢查線程,默認-1
testOnBorrow:取得對象時是否進行驗證,檢查對象是否有效,默認為fals
etestOnReturn:返回對象時是否進行驗證,檢查對象是否有效,默認為false
testWhileIdle:空閑時是否進行驗證,檢查對象是否有效,默認為false
initialSize:初始化線程數
C3P0
acquireIncrement: 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3
acquireRetryAttempts: 定義在從數據庫獲取新連接失敗后重復嘗試的次數。Default: 30
acquireRetryDelay: 兩次連接中間隔時間,單位毫秒。Default: 1000
autoCommitOnClose: 連接關閉時默認將所有未提交的操作回滾。Defaul t: false
automaticTestTable: c3p0將建一張名為Test的空表,并使用其自帶的查詢語句進行測試。如果定義了這個參數那么屬性preferredTestQuery將被忽略。你不 能在這張Test表上進行任何操作,它將只供c3p0測試使用。Default: null
breakAfterAcquireFailure: 獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數據源仍有效保留,并在下次調用getConnection()的時候繼續嘗試獲取連 接。如果設為true,那么在嘗試獲取連接失敗后該數據源將申明已斷開并永久關閉。Default: false
checkoutTimeout:當連接池用完時客戶端調用getConnection()后等待獲取新連接的時間,超時后將拋出SQLException,如設為0則無限期等待。單位毫秒。Default: 0
connectionTesterClassName: 通過實現ConnectionTester或QueryConnectionT ester的類來測試連接。類名需制定全路徑。Default: com.mchange.v2.c3p0.impl.Def aultConnectionTester
factoryClassLocation: 指定c3p0 libraries的路徑,如果(通常都是這樣)在本地即可獲得那么無需設置,默認null即可Default: null
idleConnectionTestPeriod: 每60秒檢查所有連接池中的空閑連接。Defaul t: 0
initialPoolSize: 初始化時獲取三個連接,取值應在minPoolSize與maxPoolSize之間。Default: 3
maxIdleTime: 最大空閑時間,60秒內未使用則連接被丟棄。若為0則永不丟棄。Default: 0
maxPoolSize: 連接池中保留的最大連接數。Default: 15
maxStatements: JDBC的標準參數,用以控制數據源內加載的PreparedSt atements數量。但由于預緩存的statements屬于單個connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素。如 果maxStatements與maxStatementsPerConnection均為0,則緩存被關閉。Default: 0
maxStatementsPerConnection: maxStatementsPerConnection定義了連接池內單個連接所擁有的最大緩存statements數。Default: 0
numHelperThreads:c3p0是異步操作的,緩慢的JDBC操作通過幫助進程完成。擴展這些操作可以有效的提升性能通過多線程實現多個操作同時被執行。Default: 3
overrideDefaultUser:當用戶調用getConnection()時使root用戶成為去獲取連接的用戶。主要用于連接池連接非c3p0的數據源時。Default: null
overrideDefaultPassword:與overrideDefaultUser參數對應使用的一個參數。Default: null
password:密碼。Default: null
user:用戶名。Default: null
preferredTestQuery:定義所有連接測試都執行的測試語句。在使用連接測試的情況下這個一顯著提高測試速度。注意:測試的表必須在初始數據源的時候就存在。Default: null
propertyCycle:用戶修改系統配置參數執行前最多等待300秒。Defaul t: 300
testConnectionOnCheckout:因性能消耗大請只在需要的時候使用它。如果設為true那么在每個connection提交 的時候都將校驗其有效性。建議使用idleConnectio nTestPeriod或automaticTestTable等方法來提升連接測試的性能。Default: false
testConnectionOnCheckin:如果設為true那么在取得連接的同時將校驗連接的有效性。Default: false
Proxool
acquireIncrement: 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3
fatal-sql-exception : 它是一個逗號分割的信息片段.當一個SQL異常發生時,他的異常信息將與這個信息片段進行比較.如果在片段中存在,那么這個異常將被認為是個致命錯誤 (Fatal SQL Exception ).這種情況下,數據庫連接將要被放棄.無論發生什么,這個異常將會被重擲以提供給消費者.用戶最好自己配置一個不同的異常來拋出.fatal-sql-exception-wrapper-class : 正如上面所說,你最好配置一個不同的異常來重擲.利用這個屬性,用戶可以包裝SQLException,使他變成另外一個異常.這個異常或者繼承 SQLException或者繼承字RuntimeException.proxool 自帶了2個實現:'org.logicalcobwebs.proxool .FatalSQLException' 和'org.logicalcobweb s.proxool .FatalRuntimeException' .后者更合適.
house-keeping-sleep-time : house keeper 保留線程處于睡眠狀態的最長時間,house keeper 的職責就是檢查各個連接的狀態,并判斷是否需要銷毀或者創建.
house-keeping-test-sql : 如果發現了空閑的數據庫連接.house keeper 將會用這個語句來測試.這個語句最好非常快的被執行.如果沒有定義,測試過程將會被忽略。
injectable-connection-interface : 允許proxool 實現被代理的connection對象法.
injectable-statement-interface : 允許proxool 實現被代理的Statement 對象方法.
injectable-prepared-statement-interface : 允許proxool 實現被代理的PreparedS tatement 對象方法.
injectable-callable-statement-interface : 允許proxool 實現被代理的CallableStat ement 對象方法.
jmx : 如果屬性為true,就會注冊一個消息Bean到jms服務,消息Bean對象名: "Proxool:type=Pool, name=<alias>". 默認值為false.jmx-agent-id : 一個逗號分隔的JMX代理列表(如使用MbeanServerFactory .fi ndMBeanServer(String agentId)注冊的連接池。)這個屬性是僅當"jmx"屬性設置為"true"才有效。所有注冊jmx服務器使用這個屬性是不確定的
jndi-name : 數據源的名稱
maximum-active-time : 如果housekeeper 檢測到某個線程的活動時間大于這個數值.它將會殺掉這個線程.所以確認一下你的服務器的帶寬.然后定一個合適的值.默認是5分鐘.
maximum-connection-count : 最大的數據庫連接數.
maximum-connection-lifetime : 一個線程的最大壽命.
minimum-connection-count : 最小的數據庫連接數
overload-without-refusal-lifetime : 這可以幫助我們確定連接池的狀態。如果我們已經拒絕了一個連接在這個設定值(毫秒),然后被認為是超載。默認為60秒。
prototype-count : 連接池中可用的連接數量.如果當前的連接池中的連接少于這個數值.新的連接將被建立(假設沒有超過最大可用數).例如.我們有3個活動連接2個可用連接, 而我們的prototype-count是4,那么數據庫連接池將試圖建立另外2個連接.這和 minimum-connection-count不同. minimum-connect ion-count把活動的連接也計算在內.prototype-count 是spare connections 的數量.
recently-started-threshold :這可以幫助我們確定連接池的狀態,連接數少還是多或超載。只要至少有一個連接已開始在此值(毫秒)內,或者有一些多余的可用連接,那么我們假設連接池是開啟的。默認為60秒
simultaneous-build-throttle :這是我們可一次建立的最大連接數。那就是新增的連接請求,但還沒有可供使用的連接。由于連接可以使用多線程,在有限的時間之間建立聯系從而帶來可用連 接,但是我們需要通過一些方式確認一些線程并不是立即響應連接請求的,默認是10。
statistics : 連接池使用狀況統計。 參數“10s,1m,1d”
statistics-log-level :日志統計跟蹤類型。 參數“ERROR”或 “INFO”
test-before-use : 如果為true,在每個連接被測試前都會服務這個連接,如果一個連接失敗,那么將被丟棄,另一個連接將會被處理,如果所有連接都失敗,一個新的連接將會被建立。否則將會拋出一個SQLException異常。
test-after-use : 如果為true,在每個連接被測試后都會服務這個連接,使其回到連接池中,如果連接失敗,那么將被廢棄。
trace : 如果為true,那么每個被執行的SQL語句將會在執行期被log記錄(DEBUG LEVEL).你也可以注冊一個ConnectionListener (參看ProxoolFacade)得到這些信息
BoneCP
acquireIncrement: 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3
driveClass:數據庫驅動
jdbcUrl:響應驅動的jdbcUrl
username:數據庫的用戶名
password:數據庫的密碼
idleConnectionTestPeriod:檢查數據庫連接池中控線連接的間隔時間,單位是分,默認值:240,如果要取消則設置為0
idleMaxAge:連接池中未使用的鏈接最大存活時間,單位是分,默認值:60,如果要永遠存活設置為0
maxConnectionsPerPartition:每個分區最大的連接數
minConnectionsPerPartition:每個分區最小的連接數
partitionCount:分區數,默認值2,最小1,推薦3-4,視應用而定
acquireIncrement:每次去拿數據庫連接的時候一次性要拿幾個,默認值:2
statementsCacheSize:緩存prepared statements的大小,默認值:0
releaseHelperThreads:每個分區釋放鏈接助理進程的數量,默認值:3,除非你的一個數據庫連接的時間內做了很多工作,不然過多的助理進程會影響你的性能
性能比較:
DBCP
C3P0
Proxool
BoneCP
模擬5個線程循環10次并發訪問數據庫
用時1181ms
用時860ms
用時1563ms
用時31ms
模擬10個線程循環10次并發訪問數據庫
用時1188ms
用時953ms
用時1625ms
用時63ms
模擬30個線程循環10次并發訪問數據庫
用時1250ms
用時1047ms
用時1657ms
用時156ms
模擬50個線程循環10次并發訪問數據庫
用時1406ms
用時1343ms
用時1843ms
用時172ms
模擬100個線程循環10次并發訪問數據庫
用時1641ms
用時2703ms
用時2031ms
用時532ms
模擬200個線程循環10次并發訪問數據庫
用時2093ms
用時4891ms
用時2406ms
用時936ms
模擬500個線程循環10次并發訪問數據庫
用時3219ms
用時11703ms
用時3343ms
用時1922ms
模擬800個線程循環10次并發訪問數據庫
用時4688ms
用時12063ms
用時4141ms
用時2859ms
模擬1000個線程循環10次并發訪問數據庫
用時5187ms
用時12563ms
用時4703m
用時3610ms
模擬3000個線程循環10次并發訪問數據庫
用時14094ms
用時16297ms
用時11344ms
用時11391ms
模擬5000個線程循環10次并發訪問數據庫
用時23610ms
用時22032ms
用時20125ms
用時17125ms