您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)數(shù)據(jù)庫連接池dbcp的原理及配置是怎樣的,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
1. 簡介
DBCP(DataBase Connection Pool),數(shù)據(jù)庫連接池。是 apache 上的一個 java 連接池項目,也是 tomcat 使用的連接池組件。單獨使用dbcp需要3個包:common-dbcp.jar,common-pool.jar,common-collections.jar由于建立數(shù)據(jù)庫連接是一個非常耗時耗資源的行為,所以通過連接池預(yù)先同數(shù)據(jù)庫建立一些連接,放在內(nèi)存中,應(yīng)用程序需要建立數(shù)據(jù)庫連接時直接到連接池中申請一個就行,用完后再放回去。
dbcp提供了數(shù)據(jù)庫連接池可以在spring,iBatis,hibernate中調(diào)用dbcp完成數(shù)據(jù)庫連接,框架一般都提供了dbcp連接的方法;
tomcat中也提供了dbcp的jndi設(shè)置方法,也可以不在框架中使用dbcp,單獨使用dbcp需要3個包:common-dbcp.jar,common-pool.jar,common-collections.jar
2.連接池扼要
JDBC是一套通用的Java語言與多種數(shù)據(jù)庫(文件)通訊的標(biāo)準(zhǔn)API。大部分針對數(shù)據(jù)庫服務(wù)器(例如Oracle, MySQL等等)的JDBC實現(xiàn)都是基于TCP/IP連接的客戶端-服務(wù)器端通訊方式。
當(dāng)我們需要執(zhí)行一個數(shù)據(jù)庫操作時,有下面三步:
1. 客戶端與服務(wù)器之間建立一個數(shù)據(jù)庫連接
2. 執(zhí)行某種數(shù)據(jù)庫操作
3. 斷開連接
如果每次處理都要走上面的三步,則應(yīng)用程序與數(shù)據(jù)庫服務(wù)器都要將大量的時間和資源消耗在數(shù)據(jù)連接的斷開與建立上。對于某些數(shù)據(jù)庫系統(tǒng),一個數(shù)據(jù)庫連接就是一個進程,而且數(shù)據(jù)庫連接通常要占用不少資源,如排序區(qū)/Join區(qū)等等。對于并發(fā)較大的系統(tǒng),建立一次連接然后緩存起來連續(xù)使用,直到程序結(jié)束等情況下再釋放連接,就能夠?qū)⑾到y(tǒng)資源集中在對數(shù)據(jù)庫操作的處理上,從而大大提高性能。通常情況下將數(shù)據(jù)連接的建立和斷開委托給一種能夠數(shù)據(jù)庫連接池的組件或服務(wù)進行管理。而DBCP, C3p0, Proxool等都是常用的開源的連接池組件。
就好像A公司在郊外,他們公司附近沒有出租車。如果A公司有人要出去辦事,他必須打電話給出租公司訂車,用完車后他還要付賬報銷。 這樣每個人出去一趟都必須訂車、退車和報銷。員工的很多時間白白花費在這上面了。于是A公司跟出租車公司定了一個合同,出租車公司給了他們一個車隊。要用車隨時去樓下找車隊就可以了,用完了也不必結(jié)帳,A公司統(tǒng)一跟出租車公司訂車和結(jié)帳。這個車隊就好比連接池,由公司(應(yīng)用程序)來統(tǒng)一向出租車公司(數(shù)據(jù)庫服務(wù)器)訂車(建立連接)和退車(關(guān)閉連接)。
3.DBCP的配置參數(shù)以及背后的原理
Commons-dbcp連接池的配置參數(shù)比較多,也比較復(fù)雜,主要分為
· Jdbc連接參數(shù)(username, password, url, driverClassName, connectionProperties )
· 事務(wù)處理參數(shù) (defaultAutoCommit, defaultReadOnly, defaultTransactionIsolation, defaultCatalog)
· 連接池參數(shù)(詳見下文)
· 連接池中鏈接存活性測試參數(shù)(詳見下文)
· 預(yù)處理查詢池化參數(shù)(poolPreparedStatements, maxOpenPreparedStatements)
· 丟棄失效鏈接相關(guān)參數(shù)(詳見下文)以及一個控制是否可以正常情況下處于訪問連接池包裝下的底層JDBC鏈接參數(shù)(accessToUnderlyingConnectionAllowed)
其中Jdbc鏈接參數(shù)、事務(wù)處理都跟連接池關(guān)系不大,另預(yù)處理查詢池化參數(shù)本文不詳細(xì)敘述。有關(guān)commons-dbcp的詳細(xì)參數(shù)配置信息請參考官方文檔。
4.連接池的配置
再用車隊來比喻,出租車公司每提供一輛車給A公司,A公司肯定要付出一定費用。這時候維持車隊的大小就很重要了,在項目少用車少的時候,車隊肯定要減少,不然很多空閑車輛也要付出成本;在項目多用車多的時候,肯定要擴大車隊,不然車不夠用,車隊忙不過來。A公司可以簡單地設(shè)地兩個閥值來動態(tài)調(diào)節(jié)車隊中空閑的車輛數(shù)目以滿足動態(tài)需求,一個是最小空閑車輛數(shù)(最小空空閑連接數(shù)(minIdle),當(dāng)剩余的空車數(shù)目小于該數(shù)目時,A公司就向出租車公司請求加入新車。 一個是最大空閑車輛數(shù)(maxIdle),當(dāng)剩余的車大于該數(shù)目時,就將剛剛用用完的車還給出租車公司從而減少車隊數(shù)量。
另外,這家出租車公司可能要為多個客戶服務(wù),要考慮能夠提供給A公司的最大的車數(shù)量,不能超過某個數(shù)量(maxActive)。所以A公司想出租車申請新車時首先要看下當(dāng)前正在用的車輛數(shù)目是否超過了這個最大數(shù)目,如果沒有超過那就直接申請新車,否則可以讓申請者(應(yīng)用程序中執(zhí)行請求的線程)等待 (maxWait<=0, 無限等待; maxWait>0 當(dāng)?shù)却龝r間超過 maxWait時,失敗)。
在連接池中,這幾個參數(shù)是十分重要的,官方的說明如下,是我們調(diào)節(jié)系統(tǒng)性能時需要認(rèn)真考慮的值。
Parameter | Default | Description |
initialSize | 0 | The initial number of connections that are created when the pool is started. Since: 1.2 |
maxActive | 8 | The maximum number of active connections that can be allocated from this pool at the same time, or non-positive for no limit. |
maxIdle | 8 | The maximum number of connections that can remain idle in the pool, without extra ones being released, or negative for no limit. |
minIdle | 0 | The minimum number of connections that can remain idle in the pool, without extra ones being created, or zero to create none. |
maxWait | indefinitely | The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception, or -1 to wait indefinitely. |
實際上,Dbcp 依賴于 commons-pool 來存儲連接對象。 BasicDataSource默認(rèn)使用GenericObjectPool來管理連接對象。除了請求的線程會在請求和返回連接過程中影響池中連接實例外,另有一個跑著GenericObjectPool.Evictor類型 (implements Runnable) 的實例的線程,也會影響池中的數(shù)據(jù)庫連接。
5.使用注意點
1) 如果maxIdle 設(shè)置太低,在高負(fù)載系統(tǒng)中,連接的打開時間比關(guān)閉的時間快,會引起連接池中的idle的個數(shù)上升超過maxIdle,造成頻繁的銷毀和創(chuàng)建,類似于jvm參數(shù)中的Xmx設(shè)置。
2) minIdle,該參數(shù)越接近maxIdle,性能越好,因為連接的創(chuàng)建和銷毀,都是需要消耗資源的,但是不能太大,因為在機器很空閑的時候,也會創(chuàng)建低于minIdle個數(shù)的連接,類似于jvm參數(shù)中的Xms設(shè)置。
3) PreparedStatements會在數(shù)據(jù)庫中保持打開的游標(biāo),這樣會造成一個連接超出數(shù)據(jù)庫游標(biāo)限制, 特別是當(dāng)maxOpenPreparedStatements 被設(shè)置成 default (unlimited),并且應(yīng)用在一個連接上創(chuàng)建了大量不同PreparedStatements時,為了避免這個問題, maxOpenPreparedStatements 應(yīng)該設(shè)置為一個小于數(shù)據(jù)庫在一個連接上允許打開最大游標(biāo)數(shù)。
4) poolPreparedStatements,經(jīng)過測試,開啟后的性能沒有關(guān)閉的好,或者相差不大,沒有本質(zhì)的提高。
5) 對性能影響比較大的兩個參數(shù):
testOnBorrow:這個默認(rèn)的之是true,對性能影響很大,因為每次從池中借出對象時進行一次驗證,系統(tǒng)開銷很大,實際測試中發(fā)現(xiàn),性能差距有7-10倍的樣子。
maxIdle:如果這個參數(shù)的值比maxActive低,在高負(fù)載的情況下就會產(chǎn)生很多time_waited線程。根據(jù)我們的測試結(jié)果,這個值最好和maxActive相同或者是設(shè)成-1。這樣才能在高并發(fā)下,應(yīng)用到數(shù)據(jù)庫的連接也是穩(wěn)定的使用固有的connection。否則dbcp會頻繁創(chuàng)建新的連接,丟棄老的連接。而創(chuàng)建連接這個操作,比驗證還要昂貴。
由于將maxIdle設(shè)置了一個比較高的值,應(yīng)用就會在系統(tǒng)高峰時期創(chuàng)建的連接就會維持在那里。在空閑的時候這些連接就顯得有些浪費。很多的時候數(shù)據(jù)庫機器可能會支持多個應(yīng)用,或者一個集群可能會有很多臺應(yīng)用機器。為了能這些空閑連接能夠回收,就必須設(shè)置著一個配置項。這個值和minEvictableIdleTimeMillis以及numTestsPerEvictionRun會影響evictor thread的行為。默認(rèn)timeBetweenEvictionRunsMillis的值是-1,就是不會運行。但是如果它設(shè)了一個不為-1的值,那么minEvictableIdleTimeMillis就不能設(shè)置的太短,默認(rèn)的30分鐘是個不錯的選擇。
6.配置樣例
<bean id=“dataSource” class=“org.apache.commons.dbcp.BasicDataSource” destroy- method=“close”>
<property name=“driverClassName” value=“${db_driverClassName}” />
<property name=“url” value=“${db_rul}” />
<property name=“username” value=”${db_user}” />
<property name=“password” value=”${db_passwd}” />
<property name=“maxActive” value=”${db_maxActive }” />
<property name=“initialSize” value=”${db_initialSize}” />
<property name=“maxWait” value=”${db_maxWait}” />
<property name=“maxIdle” value=”${db_maxIdle }” />
<property name=“minIdle” value=”${db_minIdle}” />
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<property name="testOnBorrow" value="false" />
<property name="testWhileIdle" value="true" />
<property name="validationQuery" value="select 1 from dual" />
<property name=“removeAbandoned” value=”true” />
<property name=“removeAbandonedTimeout” value=”180” />
</bean>
7.Mysql數(shù)據(jù)庫的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" scope="singleton" >
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/booksystem</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>mysqladmin</value>
</property>
<property name="maxActive">
<value>10</value>
</property>
<property name="initialSize">
<value>2</value>
</property>
</bean>
</beans>
關(guān)于數(shù)據(jù)庫連接池dbcp的原理及配置是怎樣的就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。