聊聊Druid(一)-- 配置與初始化

這裏以咱們經常使用在spring環境中集成druid的方式進行說明。 spring中的druid配置參考:mysql

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 
  <!-- 基本屬性 url、user、password -->
  <property name="url" value="${jdbc_url}" />
  <property name="username" value="${jdbc_user}" />
  <property name="password" value="${jdbc_password}" />
    
  <!-- 配置初始化大小、最小、最大 -->
  <property name="initialSize" value="1" />
  <property name="minIdle" value="1" /> 
  <property name="maxActive" value="20" />

  <!-- 配置獲取鏈接等待超時的時間 -->
  <property name="maxWait" value="60000" />

  <!-- 配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接,單位是毫秒 -->
  <property name="timeBetweenEvictionRunsMillis" value="60000" />

  <!-- 配置一個鏈接在池中最小生存的時間,單位是毫秒 -->
  <property name="minEvictableIdleTimeMillis" value="300000" />

  <property name="validationQuery" value="SELECT 'x'" />
  <property name="testWhileIdle" value="true" />
  <property name="testOnBorrow" value="false" />
  <property name="testOnReturn" value="false" />

  <!-- 打開PSCache,而且指定每一個鏈接上PSCache的大小 -->
  <property name="poolPreparedStatements" value="true" />
  <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />

  <!-- 配置監控統計攔截的filters -->
  <property name="filters" value="stat" /> 
</bean>

一般來講,只須要修改initialSize、minIdle、maxActive。spring

若是用Oracle,則把poolPreparedStatements配置爲true,mysql能夠配置爲false。分庫分表較多的數據庫,建議配置爲false。sql

能夠看到配置中指定了初始化方法:init。在spring初始化這個bean時會調用init方法進行初始化。初始化流程以下:數據庫

1. 獲取全局同步鎖
2. 記錄當前線程調用棧
3. 初始化各類idSeed  -- 
4. 執行filter的init方法進行filter的初始化
5. 核心配置的校驗。包括不限於:maxActive,timeBetweenLogStatsMillis和maxEvictableIdleTimeMillis
6. 建立Driver。(MockDriver或者Driver)
7. 初始化ExceptionSorter,validConnectionChecker
8. 初始化dataSourceStat。全局數據源stat仍是單獨stat
9. 初始化各類池。connections,evictConnections和keepAliveConnections
10. 建立initSize個鏈接
11. 啓動各類線程。日誌統計線程,鏈接建立線程以及鏈接銷燬檢測線程
12. emptySignal
13. 釋放全局同步鎖

說明:網絡

一、使用了一個size爲2的countdownLatch,是爲了在初始化鏈接建立線程和鏈接銷燬檢測線程都啓動後再執行後續的初始化步驟。默認是每一個數據源建立一個鏈接建立線程和鏈接銷燬檢測線程。當數據源十分多時,會致使線程數劇增,因此提供了createScheduler和destroyScheduler實現線程池。session

二、對於keepAlive的理解。ui

在Druid-1.0.27以前的版本,DruidDataSource建議使用TestWhileIdle來保證鏈接的有效性,但仍有不少場景須要對鏈接進行保活處理(好比)。在1.0.28版本以後,新加入keepAlive配置,缺省關閉。打開KeepAlive以後的效果url

1. 初始化鏈接池時會填充到minIdle數量(初始化的時候並無判斷keepAlive窩)。
2. 鏈接池中的minIdle數量之內的鏈接,空閒時間超過minEvictableIdleTimeMillis,則會執行keepAlive操做。
3. 當網絡斷開等緣由產生的由ExceptionSorter檢測出來的死鏈接被清除後,自動補充鏈接到minIdle數量。

上述內容來自Druid 官方文檔。如下是我的的理解:線程

  a)是否在要保持connections中的鏈接數不小於minIdle日誌

  b)使用keepAlive,在鏈接時間已經超過minIdle,可是未達到maxIdle以前會保持鏈接而不丟棄,具體查看removeAbandoned方法,上述的第二點也是在DestoryTask中調用removeAbandoned實現的。

三、初始化完成以後會註冊一個dataSource的MBEAN。

四、關於ExceptionSorter。

  當一個鏈接產生不可恢復的異常時,例如Oracle error_code_28 session has been killed,必須馬上從鏈接池中逐出,不然會產生大量錯誤。目前只有Druid和JBoss DataSource實現了ExceptionSorter。

相關文章
相關標籤/搜索