溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

數(shù)據(jù)庫連接池dbcp的原理及配置是怎樣的

發(fā)布時間:2021-11-30 17:07:45 來源:億速云 閱讀:183 作者:柒染 欄目:數(shù)據(jù)庫

這篇文章將為大家詳細(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
線程池啟動時初始化的連接數(shù) 

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.
最大活動連接數(shù),如果非正整數(shù),則不做限制。 

maxIdle

8

The maximum number of connections that can remain idle in the pool, without extra ones being released, or negative for no limit.
最大空閑連接數(shù)。 

minIdle

0

The minimum number of connections that can remain idle in the pool, without extra ones being created, or zero to create none.
最小空閑連接數(shù)。 

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.
(在沒有連接可用時)連接池等待一個數(shù)據(jù)連接可用時的以毫秒計的最大等待時間,超時以后拋出異常, -1 則將無限等待 

實際上,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é)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(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)容。

AI