天天看點

Java資料庫連接配接池比較(c3p0,dbcp,proxool和BoneCP)

java架構資料庫連接配接池比較(c3p0,dbcp和proxool,bonec) 

現在常用的開源資料連接配接池主要有c3p0,dbcp,proxool,bonecp,其中: 

¨         hibernate開發組推薦使用c3p0; 

¨         spring開發組推薦使用dbcp (dbcp連接配接池有weblogic連接配接池同樣的問題,就是強行關閉連接配接或資料庫重新開機後,無法reconnect ,告訴連接配接被重置,這個設定可以解決); 

¨         hibernate in action推薦使用c3p0和proxool; 

下面具體就每種連接配接池的調研結果進行說明: 

1. apache-dbcp 

Ø basicdatasource 相關的參數說明 

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:取得對象時是否進行驗證,檢查對象是否有效,預設為false 

testonreturn:傳回對象時是否進行驗證,檢查對象是否有效,預設為false 

testwhileidle:空閑時是否進行驗證,檢查對象是否有效,預設為false 

Ø 在使用dbcp的時候,如果使用預設值,則資料庫連接配接因為某種原因斷掉後,再從連接配接池中取得連接配接又不進行驗證,這時取得的連接配接實際上就會是無效的資料庫連接配接。是以為了防止獲得的資料庫連接配接失效,在使用的時候最好保證: 

validationquery:select count(*) from dual 

testonborrow、testonreturn、testwhileidle:最好都設為true 

minevictableidletimemillis:大于0 ,進行連接配接空閑時間判斷,或為0,對空閑的連接配接不進行驗證 

timebetweenevictionrunsmillis:失效檢查線程運作時間間隔,如果小于等于0,不會啟動檢查線程 

Ø ps:在構造genericobjectpool [basicdatasource在其createdatasource () 方法中也會使用genericobjectpool] 時,會生成一個内嵌類evictor,實作自runnable接口。如果timebetweenevictionrunsmillis大于0,每過timebetweenevictionrunsmillis毫秒evictor會調用evict()方法,檢查對象的閑置時間是否大于 minevictableidletimemillis毫秒(_minevictableidletimemillis小于等于0時則忽略,預設為30分鐘),是則銷毀此對象,否則就激活并校驗對象,然後調用ensureminidle方法檢查確定池中對象個數不小于_minidle。在調用returnobject方法把對象放回對象池,首先檢查該對象是否有效,然後調用poolableobjectfactory 的passivateobject方法使對象處于非活動狀态。再檢查對象池中對象個數是否小于maxidle,是則可以把此對象放回對象池,否則銷毀此對象 

Ø 上述特性的可設定性已在代碼中驗證,具體性能是否能實作有待實際驗證 

2. c3p0 

Ø c3p0的官方example中使用的資料源為combopooleddatasource,網上一篇文章詳細介紹了c3p0連接配接池配置中各項含義[這些配置項的含義在下載下傳解壓c3p0的壓縮包之後目錄的doc\index.html中的configuration部分也有詳細的介紹,這裡偷下懶:p],現摘錄如下: 

<c3p0-config> 

<default-config> 

<!--當連接配接池中的連接配接耗盡的時候c3p0一次同時擷取的連接配接數。default: 3 --> 

<property name="acquireincrement">3</property> 

<!--定義在從資料庫擷取新連接配接失敗後重複嘗試的次數。default: 30 --> 

<property name="acquireretryattempts">30</property> 

<!--兩次連接配接中間隔時間,機關毫秒。default: 1000 --> 

<property name="acquireretrydelay">1000</property> 

<!--連接配接關閉時預設将所有未送出的操作復原。default: false --> 

<property name="autocommitonclose">false</property> 

<!--c3p0将建一張名為test的空表,并使用其自帶的查詢語句進行測試。如果定義了這個參數那麼 

屬性preferredtestquery将被忽略。你不能在這張test表上進行任何操作,它将隻供c3p0測試 

使用。default: null--> 

<property name="automatictesttable">test</property> 

<!--擷取連接配接失敗将會引起所有等待連接配接池來擷取連接配接的線程抛出異常。但是資料源仍有效 

保留,并在下次調用getconnection()的時候繼續嘗試擷取連接配接。如果設為true,那麼在嘗試 

擷取連接配接失敗後該資料源将申明已斷開并永久關閉。default: false--> 

<property name="breakafteracquirefailure">false</property> 

<!--當連接配接池用完時用戶端調用getconnection()後等待擷取新連接配接的時間,逾時後将抛出 

sqlexception,如設為0則無限期等待。機關毫秒。default: 0 --> 

<property name="checkouttimeout">100</property> 

<!--通過實作connectiontester或queryconnectiontester的類來測試連接配接。類名需制定全路徑。 

default: com.mchange.v2.c3p0.impl.defaultconnectiontester--> 

<property name="connectiontesterclassname"></property> 

<!--指定c3p0 libraries的路徑,如果(通常都是這樣)在本地即可獲得那麼無需設定,預設null即可 

default: null--> 

<property name="factoryclasslocation">null</property> 

<!--strongly disrecommended. setting this to true may lead to subtle and bizarre bugs. 

(文檔原文)作者強烈建議不使用的一個屬性--> 

<property name="forceignoreunresolvedtransactions">false</property> 

<!--每60秒檢查所有連接配接池中的空閑連接配接。default: 0 --> 

<property name="idleconnectiontestperiod">60</property> 

<!--初始化時擷取三個連接配接,取值應在minpoolsize與maxpoolsize之間。default: 3 --> 

<property name="initialpoolsize">3</property> 

<!--最大空閑時間,60秒内未使用則連接配接被丢棄。若為0則永不丢棄。default: 0 --> 

<property name="maxidletime">60</property> 

<!--連接配接池中保留的最大連接配接數。default: 15 --> 

<property name="maxpoolsize">15</property> 

<!--jdbc的标準參數,用以控制資料源内加載的preparedstatements數量。但由于預緩存的statements 

屬于單個connection而不是整個連接配接池。是以設定這個參數需要考慮到多方面的因素。 

如果maxstatements與maxstatementsperconnection均為0,則緩存被關閉。default: 0--> 

<property name="maxstatements">100</property> 

<!--maxstatementsperconnection定義了連接配接池内單個連接配接所擁有的最大緩存statements數。default: 0 --> 

<property name="maxstatementsperconnection"></property> 

<!--c3p0是異步操作的,緩慢的jdbc操作通過幫助程序完成。擴充這些操作可以有效的提升性能 

通過多線程實作多個操作同時被執行。default: 3--> 

<property name="numhelperthreads">3</property> 

<!--當使用者調用getconnection()時使root使用者成為去擷取連接配接的使用者。主要用于連接配接池連接配接非c3p0 

的資料源時。default: null--> 

<property name="overridedefaultuser">root</property> 

<!--與overridedefaultuser參數對應使用的一個參數。default: null--> 

<property name="overridedefaultpassword">password</property> 

<!--密碼。default: null--> 

<property name="password"></property> 

<!--定義所有連接配接測試都執行的測試語句。在使用連接配接測試的情況下這個一顯著提高測試速度。注意: 

測試的表必須在初始資料源的時候就存在。default: null--> 

<property name="preferredtestquery">select id from test where id=1</property> 

<!--使用者修改系統配置參數執行前最多等待300秒。default: 300 --> 

<property name="propertycycle">300</property> 

<!--因性能消耗大請隻在需要的時候使用它。如果設為true那麼在每個connection送出的 

時候都将校驗其有效性。建議使用idleconnectiontestperiod或automatictesttable 

等方法來提升連接配接測試的性能。default: false --> 

<property name="testconnectiononcheckout">false</property> 

<!--如果設為true那麼在取得連接配接的同時将校驗連接配接的有效性。default: false --> 

<property name="testconnectiononcheckin">true</property> 

<!--使用者名。default: null--> 

<property name="user">root</property> 

<!--早期的c3p0版本對jdbc接口采用動态反射代理。在早期版本用途廣泛的情況下這個參數 

允許使用者恢複到動态反射代理以解決不穩定的故障。最新的非反射代理更快并且已經開始 

廣泛的被使用,是以這個參數未必有用。現在原先的動态反射與新的非反射代理同時受到 

支援,但今後可能的版本可能不支援動态反射代理。

Ø 從配置項的内容來看,c3p0和dbcp都有比較詳細的有關連接配接檢測保證的配置,我們可以看到c3p0可以控制資料源内加載的preparedstatements數量,并且可以設定幫助線程的數量來提升jdbc操作的速度,這些是dbcp未提供的;另外從網絡上的評價來看,dbcp出現bug的頻率要大于c3p0,不過這一點有待于我們自己實際的檢測。 

3. proxool 

Ø proxool的使用和dbcp以及c3p0稍有不同,我們需要并且隻需要在使用基本的java.sql.drivermanager之前加載org.logicalcobwebs.proxool.proxooldriver驅動類,并且按照proxool定義的url格式 ["proxool." + alias + ":" + driverclass + ":" + driverurl ,其中alias是為連接配接池自定義的别名] 來獲得connection;具體的可以參看proxool doc下的userguide,或本文所附的示例代碼。下面對連接配接池的特性配置作詳細說明 [這個是自己翻譯的,不一定準确,有問題時請參看doc下的properties ~]。 

n fatal-sql-exception 

以逗号隔開的異常清單,當設定了此項之後,每當出現sqlexception時都将與清單中異常項作比較,如果比對則認為出現fatal異常,這将導緻connection被丢棄,并且不論出現任何情況該異常将被重抛一次以通知使用者發生的情況。預設值為null 

n fatal-sql-exception-wrapper-class 

如果配置了fatal-sql-exception,則預設的操作是丢棄引起sqlexception的原因而隻是抛出原始異常。使用fatal-sql-exception-wrapper-class這個特性可以将sqlexception包裝到繼承sqlexception或runtimeexception的任何異常類裡。proxool提供了兩個類供使用fatalsqlexception和fatalruntimeexception;使用這兩個類的話就将該選項設定為'org.logicalcobwebs.proxool.fatalsqlexception'或者'org.logicalcobwebs.proxool.fatalruntimeexception'。預設值為null 

n house-keeping-sleep-time 

proxool自動偵察各個連接配接狀态的時間間隔(毫秒),偵察到空閑的連接配接就馬上回收,逾時的銷毀,預設值為30秒 

n house-keeping-test-sql 

如果偵察線程發現閑置連接配接,則會使用這個sql語句來對這些連接配接進行檢查;這項設定的語句應該能夠被很快的執行,例如查詢目前時間 [info.setproperty("proxool.house-keeping-test-sql", "select current_date");] 。如果不設定則該選項被忽略 

n injectable-connection-interface、injectable-statement-interface、injectable-prepared-statement-interface、injectable-callable-statement-interface 

n jmx 

如果此項設為true,則連接配接池将被以名稱"proxool:type=pool, name=<alias>"注冊為jms server的mbean。預設值為false 

n jmx-agent-id 

當且僅當jmx選項設為true時使用,為以逗号分隔的連接配接持注冊到的jms代理名稱清單;如果不設定則所有注冊的jmx server都将被使用 

n maximum-active-time 

線程最大存活時間,超過此時間的線程将被守護線程kill掉,預設值為5分鐘 

n maximum-connection-count 

到資料庫的最大連接配接數,超過了這個連接配接,再有請求時,就排在隊列中等候,最大的等待請求數由simultaneous-build-throttle決定;預設值為15 

n maximum-connection-lifetime 

連接配接最大存活時間,毫秒為機關,預設值為4小時 

n minimum-connection-count 

不管是否被使用都保持開放的最小連接配接數,預設值為5 

n overload-without-refusal-lifetime 

用來判斷連接配接池狀态,如果在此選項設定時間内(毫秒為機關)拒絕了連接配接,則認為過負載。預設值為60秒 

n prototype-count 

最少保持的空閑連接配接數,注意與minimum-connection-count區分。預設值為0 

n simultaneous-build-throttle 

最大的等待請求數,預設值為10 

n test-before-use 

如果設為true則connection在使用前将以house-keeping-test-sql設定的語句測試,如果測試不通過則該connection被丢棄并會重新配置設定一個connection。預設為false 

n test-after-use 

如果設為true則connection在關閉(放回連接配接池)前将以house-keeping-test-sql設定的語句測試,如果測試不通過connection将被丢棄。預設值為false 

Ø 與其它連接配接池特性的設定方法不同,proxool不提供相應的set方法,所有特性都要以諸如info.setproperty("proxool.jmx", "false");方式設定 

Ø proxool與dbcp以及c3p0的性能比較,網上衆說紛纭,有待我們自己的測試 

4 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,除非你的一個資料庫連接配接的時間内做了很多工作,不然過多的助理程序會影響你的性能 

1 c3p0、dbcp、proxool、bonecp比較 

1.1 測試環境: 

作業系統:windows xp sp3 

資料庫:mysql 5.1 

1.2 測試條件: 

initialsize=30; 

maxsize=200; 

minsize=30; 

其餘參數為預設值; 

利用java代碼模拟多線程對這三種資料庫連接配接池進行測試(代碼省略),通過花費的時間判斷效率 

 模拟10個線程循環10次并發通路資料庫 

dbcp用時1188ms 

c3p0用時953ms 

proxool用時1625ms 

bonecp用時63ms 

模拟50個線程循環10次并發通路資料庫 

dbcp用時1406ms 

c3p0用時1343ms 

proxool用時1843ms 

bonecp用時172ms 

模拟100個線程循環10次并發通路資料庫 

dbcp用時1641ms 

c3p0用時2703ms 

proxool用時2031ms 

bonecp用時532ms 

模拟200個線程循環10次并發通路資料庫 

dbcp用時2093ms 

c3p0用時4891ms 

proxool用時2406ms 

bonecp用時936ms 

模拟500個線程循環10次并發通路資料庫 

dbcp用時3219ms 

c3p0用時11703ms 

proxool用時3343ms 

bonecp用時1922ms 

 模拟1000個線程循環10次并發通路資料庫 

dbcp用時5187ms 

c3p0用時12563ms 

proxool用時4703ms 

bonecp用時3610ms 

4.4測試結果分析: 

         bonecp一直保持性能最佳 

特别說明:尊重作者的勞動成果,轉載請注明出處哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp21

下一篇: 順序表