dbcp的基本配置及相關問題總結
1. 引入dbcp (選擇1.4)
Java程式碼
<dependency>
</dependency>
<dependency>
</dependency>
2. dbcp的基本配置
相關配置說明:
initialSize :連線池啟動時建立的初始化連線數量(預設值為0)
maxActive :連線池中可同時連線的最大的連線數(預設值為8,調整為20,高峰單機器在20併發左右,自己根據應用場景定)
maxIdle:連線池中最大的空閒的連線數,超過的空閒連線將被釋放,如果設定為負數表示不限制(預設為8個,maxIdle不能設定太小,因為假如在高負載的情況下,連線的開啟時間比關閉的時間快,會引起連線池中idle的個數上升超過maxIdle,而造成頻繁的連線銷燬和建立,類似於jvm引數中的Xmx設定)
minIdle:連線池中最小的空閒的連線數,低於這個數量會被建立新的連線(預設為0,調整為5,該引數越接近maxIdle,效能越好,因為連線的建立和銷燬,都是需要消耗資源的;但是不能太大,因為在機器很空閒的時候,也會建立低於minidle個數的連線,類似於jvm引數中的Xmn設定)
maxWait
poolPreparedStatements:開啟池的prepared(預設是false,未調整,經過測試,開啟後的效能沒有關閉的好。)
maxOpenPreparedStatement
minEvictableIdleTimeMill
(預設為30分鐘,可以適當做調整,需要和後端服務端的策略配置相關)
removeAbandonedTimeout
removeAbandoned
removeAbandoned引數解釋:
如果開啟了removeAbandoned,當getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)時被觸發.
舉例當maxActive=20, 活動連線為18,空閒連線為1時可以觸發"removeAbandoned".但是活動連線只有在沒有被使用的時間超過"removeAbandonedTimeout"時才被回收
logAbandoned: 標記當連線被回收時是否列印程式的stack traces日誌(預設為false,未調整)
一般會是幾種情況出現需要removeAbandoned:
程式碼未在finally釋放connection , 不過我們都用sqlmapClientTemplate,底層都有連結釋放的過程
遇到資料庫死鎖。以前遇到過後端儲存過程做了鎖表操作,導致前臺叢集中連線池全都被block住,後續的業務處理因為拿不到連結所有都處理失敗了。
一份優化過的配置:
基本配置程式碼
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
</bean>
2. dbcp的連結validate配置
dbcp是採用了commons-pool做為其連線池管理,testOnBorrow,testOnReturn, testWhileIdle是pool是提供的幾種校驗機制,通過外部鉤子的方式回撥dbcp的相關資料庫連結(validationQuery)校驗
dbcp相關外部鉤子類:PoolableConnectionFactor
dbcp通過GenericObjectPool這一入口,進行連線池的borrow,return處理
testOnBorrow : 顧明思義,就是在進行borrowObject進行處理時,對拿到的connection進行validateObject校驗
testOnReturn : 顧明思義,就是在進行returnObject對返回的connection進行validateObject校驗,個人覺得對資料庫連線池的管理意義不大
testWhileIdle : 關注的重點,GenericObjectPool中針對pool管理,起了一個Evict的TimerTask定時執行緒進行控制(可通過設定引數timeBetweenEvictionRunsM
timeBetweenEvictionRunsM
validateQuery, 代表檢查的sql
validateQueryTimeout,代表在執行檢查時,通過statement設定,statement.setQueryTimeout(validationQueryTimeout)
numTestsPerEvictionRun,代表每次檢查連結的數量,建議設定和maxActive一樣大,這樣每次可以有效檢查所有的連結.
Validate配置程式碼
<property name="testWhileIdle"><value>true</value></property> <!-- 開啟檢查,用非同步執行緒evict進行檢查 -->
目前網站的應用大部分的瓶頸還是在I/O這一塊,大部分的I/O還是在資料庫的這一層面上,每一個請求可能會呼叫10來次SQL查詢,如果不走事務,一個請求會重複獲取連結,如果每次獲取連結都進行validateObject,效能開銷不是很能接受,可以假定一次SQL操作消毫0.5~1ms(一般走了網路請求基本就這數)
網站異常資料庫重啟,網路異常斷開的頻率是非常低的,一般也就在資料庫升級,演習維護時才會進行,而且一般也是選在晚上,訪問量相對比較低的請求,而且一般會有人員值班關注,所以非同步的validateObject是可以接受,但一個前提需要確保能保證在一個合理的時間段內,資料庫能完成自動重聯。
從程式碼層面簡單介紹下dbcp的validate實現:
1.
Java程式碼
public interface PoolableObjectFactory {
}
public interface PoolableObjectFactory {
}
2. dbcp實現的pool從池管理操作
這裡貼了一個相關validate程式碼,具體類可見:PoolableConnectionFactor
Java程式碼
public class PoolableConnectionFactor
......
public boolean validateObject(Object obj) { //驗證validateObject
public void validateConnection(Connection conn) throws SQLException {