Spring使用proxool連接池 管理數據源

原文地址:http://blog.sina.com.cn/s/blog_7ffb8dd501019bon.html

一、Proxool連接池簡介及其配置屬性概述

 Proxool是一種Java數據庫連接池技術。是sourceforge下的一個開源項目,這個項目提供一個健壯、易用的連接池,最爲關鍵的是這個連接池提供監控的功能,方便易用,便於發現連接泄漏的情況。
目前是和DBCP以及C3P0一起,最爲常見的三種JDBC連接池技術。
日前,Hibernate官方宣佈由於Bug太多不再支持DBCP,而推薦使用Proxool或C3P0。
 要使用Proxool首先要導入Proxool.jar,此jar包
可以在下載的Hibernate包中hibernate-release-4.1.7.Final\lib\optional\proxool\中找到;也可以到官網:http://nchc.dl.sourceforge.net/sourceforge/proxool/proxool-0.9.1-source.zip下載它的源碼,下載完後解壓,把proxool.jar和proxool-cglib.jar放入你要配置的項目的lib目錄下.。
  
  simultaneous-build-throttle:
是指在任一時刻,可以(同時)建立的最大連接數,也就是說,就是已經請求的、但還沒可用的新連接數量。因爲連接可以用多線程建立,從決定要建立連接到連接可用是需要一定時間的,所以我們需要一些方式來避免大量的線程想同時建立連接。(我們本應該找一個更聰明的方式來解決這個問題,總有一天我們會找到的)默認值是10
當我使用140個用戶,進行壓力測試時,發現偶爾,會有多於10個要求同時建立連接的請求,當請求數量超過限定的數值時,會出現連接失敗的情況。
因此結論就是,當數據庫併發連接可能會比較高的應用,這個值應該適當的設大一點。
如果併發請求很高,可能出現的bug爲

Caused by: java.sql.SQLException: We are already in the process ofmaking 11 connections and the number of simultaneous builds hasbeen throttled to 10

maximum-active-time:

如果一個線程活動時間超過這個數值,線程會被殺死。所以要確保這個數值設置得比最慢的響應時間長。默認是5分鐘。守護進程會把連接池中多餘的可用線程(未用的、超過這個時間的)殺死,最終保留的連接數量就是minimum-connection-count規定的數量。守護進程會根據house-keeping-sleep-time參數設置的時間隔定時檢查。

maximum-connection-lifetime:
指一個連接最大的存活時間(毫秒爲單位),超過這個時間,連接會被殺死。默認值是4小時。

overload-without-refusal-lifetime:
這個參數幫助我們確定連接池的狀態,如果在這個時間閥值內(單位爲毫秒)拒絕了一個連接,就認爲是過載了。默認值是60。

alias:
數據源的別名

driver-url:url連接串,須確定用戶名和密碼

driver-class:
驅動名

username:用戶名(proxool沒有使用,但是不能沒有)

password:密碼(proxool沒有使用,但是不能沒有)

maximum-new-connections:
沒有空閒連接可以分配而在隊列中等候的最大請求數,超過這個請求數的用戶連接就不會被接受

test-before-use:
如果連接池在運行當中,出現網絡或者數據庫故障而無法連接到數據庫,在恢復正常以後,由於連接是在連接池中持久保存的,會出現連接仍然不可用的情況,這時連接池裏的連接實際上都是壞連接,怎麼讓連接池可以自動重連清除這些壞連接呢?只要配置了test-before-use參數,即每次取出連接都檢查連接是否可用,就可以做到讓連接池實現在故障恢復後自動重連接

需要注意一點,對於Mysql數據庫還必須在連接參數里加上autoReconnect=true參數,否則即使打開了test-before-use 參數,仍然不能重連接!

fatal-sql-exception:
它是一個逗號分割的信息片段.當一個SQL異常發生時,他的異常信息將與這個信息片段進行比較.如果在片段中存在,那麼這個異常將被認爲是個致命錯誤(FatalSQL Exception).這種情況下,數據庫連接將要被放棄.無論發生什麼,這個異常將會被重擲以提供給消費者.用戶最好自己配置一個不同的異常來拋出.

fatal-sql-exception-wrapper-class:
正如上面所說,你最好配置一個不同的異常來重擲.利用這個屬性,用戶可以包裝SQLException,使他變成另外一個異常.這個異常或者繼承SQLException或者繼承字RuntimeException.proxool自帶了2個實現:’org.logicalcobwebs.proxool.FatalSQLException’和’org.logicalcobwebs.proxool.FatalRuntimeException’ .後者更合適.

house-keeping-sleep-time:
proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閒的連接就馬上回收,超時的銷燬 默認30秒)

house keeper 保留線程處於睡眠狀態的最長時間,house keeper的職責就是檢查各個連接的狀態,並判斷是否需要銷燬或者創建.

house-keeping-test-sql:
如果發現了空閒的數據庫連接.house keeper將會用這個語句來測試.這個語句最好非常快的被執行.如果沒有定義,測試過程將會被忽略。

一般mysql可用select SYSDATE ,Oracle可用 select sysdate from dual 或者select 1 from dual

injectable-connection-interface:允許proxool實現被代理的connection對象的方法.

injectable-statement-interface: 允許proxool實現被代理的Statement對象方法.
injectable-prepared-statement-interface:允許proxool實現被代理的PreparedStatement 對象方法.
injectable-callable-statement-interface:允許proxool實現被代理的CallableStatement 對象方法.
jndi-name: 數據源的名稱

maximum-active-time: 如果housekeeper檢測到某個線程的活動時間大於這個數值.它將會殺掉這個線程.所以確認一下你的服務器的帶寬.然後定一個合適的值.默認是5分鐘.
maximum-connection-count:
The maximum number of connections to the database. Default is15.
最大的數據庫連接數.默認是15
minimum-connection-count: 最小的數據庫連接數,默認是5

prototype-count:
連接池中可用的連接數量.如果當前的連接池中的連接少於這個數值.新的連接將被建立(假設沒有超過最大可用數).例如.我們有3個活動連接2個可用連接,而我們的prototype-count是4,那麼數據庫連接池將試圖建立另外2個連接.這和minimum-connection-count不同.minimum-connection-count把活動的連接也計算在內.prototype-count 是spareconnections 的數量.

statistics: 連接池使用狀況統計。 參數“10s,1m,1d”
statistics-log-level: 日誌統計跟蹤類型。 參數“ERROR”或 “INFO”

trace: 如果爲true,那麼每個被執行的SQL語句將會在執行期被log記錄(DEBUGLEVEL).你也可以註冊一個ConnectionListener (參看ProxoolFacade)得到這些信息.
verbose: 詳細信息設置。 參數 bool 值

二、Spring中配置Proxool連接池管理數據源方式與步驟

 方式一、

   在Spring的"applicationContext.xml"中的dataSource bean定義——

<bean id="dataSource"
   class="org.logicalcobwebs.proxool.ProxoolDataSource">
   <property name="driver">
       <value>com.mysql.jdbc.Driver</value>
   </property>
   <property name="driverUrl">
       <value>jdbc:mysql://localhost:3306/dbname?user=yourname&amp;password=yourpass</value>
   </property>
   <property name="user" value="yourname"/>
   <property name="password" value="yourpass"/>
   <property name="alias" value="Pool_dbname"/>
   <property name="houseKeepingSleepTime" value="90000"/>
   <property name="prototypeCount" value="0"/>
   <property name="maximumConnectionCount" value="50"/>
   <property name="minimumConnectionCount" value="2"/>
   <property name="simultaneousBuildThrottle"value="50" />
   <property name="maximumConnectionLifetime"value="14400000" />
   <property name="houseKeepingTestSql" value="selectCURRENT_DATE" />
</bean>


   第一種方式需要把用戶名和密碼寫在連接串裏面,ProxoolDataSource類提供的user,password屬性似乎沒有什麼用。無論提供什麼,它都會以空用戶名、密碼去連接數據庫。這可能是ProxoolRC0.93的一個bug,實在讓人惱火,不知道最新的0.9.1有沒有fix這個bug。不過配置中的user,password兩個屬性還必須設置,否則hibernate會報空指針錯誤。

 方式二:
   步驟一:在Spring的"applicationContext.xml"中的dataSource bean定義——

<bean id="dataSource"
   class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <propertyname="driverClassName">
       <value>org.logicalcobwebs.proxool.ProxoolDriver</value>
   </property>
   <property name="url">
       <value>proxool.Pool_dbname</value>
   </property>
</bean>


   步驟二、預先在"web.xml"先配置好Proxool連接池,配置如下:
<!--管理proxool配置文件-->
<servlet>
   <servlet-name>proxoolServletConfigurator</servlet-name>
   <servlet-class>     org.logicalcobwebs.proxool.configuration.ServletConfigurator
   </servlet-class>
   <init-param>
       <param-name>xmlFile</param-name>
       <param-value>WEB-INF/proxool.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>
<!--查看proxool運行情況,也可以不作配置的
 <servlet>
 <servlet-name>proxooladmin</servlet-name>
 <servlet-class>
  org.logicalcobwebs.proxool.admin.servlet.AdminServlet
 </servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>proxooladmin</servlet-name>
 <url-pattern>/proxooladmin</url-pattern>
 </servlet-mapping>
-->

<servlet>
   <servlet-name>context</servlet-name>
   <servlet-class>
       org.springframework.web.context.ContextLoaderServlet
   </servlet-class>
   <load-on-startup>2</load-on-startup>
</servlet>


 注意:
 把<load-on-startup>的值設爲1,值越小級別就越高,就先被加載初始化。一定要先於applicationContext.xml的加載;第二種方式下Spring的上下文加載如果想使用listener方式(Struts2要求),
則與連接池有關的Bean全得延遲初始化。因爲listener比servlet優先初始化,
如果相關Bean不是lazy-init的話,則啓動服務器時會出現Bean找不到連接定義的異常:
Problem 
    org.logicalcobwebs.proxool.ProxoolException: Attempt to refer to a unregistered pool by its 
    alias 'db'。

listener方式如下:
 <listener>
 <listener-class>
     org.springframework.web.context.ContextLoaderListener
 </listener-class>
 </listener>

步驟三、在/WEB-INF/下添加proxool的配置文件:
proxool.xml
proxool的配置文件可以採用xmlFile"proxool.xml"或者propertyFile"proxool.properties"

"proxool.xml"格式如下
 

<?xml version="1.0" encoding="UTF-8"?>
<proxool-config>
 
  <proxool>
 
     <alias>Pool_dbname</alias>
 
     <driver-url>jdbc:mysql://localhost:3306/dbname</driver-url>
 
     <driver-class>com.mysql.jdbc.Driver</driver-class>
 
     <driver-properties>
 
     <property name="user" value="yourname"/>
 
     <property name="password" value="yourpass"/>
 
     </driver-properties>
 
     <house-keeping-sleep-time>60000</house-keeping-sleep-time>
 
     <maximum-connection-count>20</maximum-connection-count> 
 
     <minimum-connection-count>2</minimum-connection-count>
 
     <prototype-count>0</prototype-count>
 
     <simultaneous-build-throttle>20</simultaneous-build-throttle>
 
     <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
 
     <statistics>15s,10m,1d</statistics>
 
     <statistics-log-level>INFO</statistics-log-level>
 
  </proxool>
 
  <proxool>
 
   <!--可以配置多個庫-->
 
  </proxool>
</proxool-config>


"proxool.properties"格式如下:


jdbc-0.proxool.alias=Pool_dbname
jdbc-0.proxool.driver-url=jdbc:mysql://localhost:3306/dbname
jdbc-0.proxool.driver-class=com.mysql.jdbc.Driver
jdbc-0.user=yourname
jdbc-0.password=yourpass
jdbc-0.proxool.house-keeping-sleep-time=60000
jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE
jdbc-0.proxool.maximum-connection-count=10
jdbc-0.proxool.minimum-connection-count=3
jdbc-0.proxool.maximum-connection-lifetime=18000000
jdbc-0.proxool.prototype-count=3
jdbc-0.proxool.simultaneous-build-throttle=10
jdbc-0.proxool.recently-started-threshold=60000
jdbc-0.proxool.overload-without-refusal-lifetime=50000
jdbc-0.proxool.maximum-active-time=60000
jdbc-0.proxool.verbose=true
jdbc-0.proxool.trace=true
jdbc-0.proxool.fatal-sql-exception=Fatal error

jdbc-2.proxool.alias=Pool_dbname2
……
<!--可以配置多個庫-->

至此,已完成所有配置。
-----------------------------------------------------------

個人比較傾向於第二種配置方式,
 1:可以避免在Spring的"applicationContext.xml"中寫一大堆參數,
尤其是避免了driverUrl中帶用戶名密碼(這會顯示在proxool包中帶的
org.logicalcobwebs.proxool.admin.servlet.AdminServlet輸出的頁面中)
 2:proxool連接池可以在tomcat啓動時就初始化好,可以提高第一次訪問web時的連接速度。


三、更詳細的配置示例
 1、更詳細的proxool.xml的配置屬性說明:
 <?xmlversion="1.0" encoding="ISO-8859-1"?>
<!--
Properties for Proxool Configurator testing. Defines the sameparameters as
TestHelper.buildCompleteAlternativeProperties()
-->
<something-else-entirelyxmlns="http://sumthin.else.entirely" xmlns:proxool="The latestversion is available athttp://proxool.sourceforge.net/xml-namespace">
   <proxool:proxool>
       <proxool:alias>xml-test-ns</proxool:alias>
       <proxool:driver-url>jdbc:hsqldb:db/test</proxool:driver-url>
       <proxool:driver-class>org.hsqldb.jdbcDriver</proxool:driver-class>
       <proxool:driver-properties>
           <proxool:property name="user"value="sa"/>
           <proxool:property name="password"value=""/>
       </proxool:driver-properties>
       <proxool:house-keeping-sleep-time>40000</proxool:house-keeping-sleep-time>
       <proxool:house-keeping-test-sql>selectCURRENT_DATE</proxool:house-keeping-test-sql>
       <proxool:maximum-connection-count>10</proxool:maximum-connection-count>
       <proxool:minimum-connection-count>3</proxool:minimum-connection-count>
       <proxool:maximum-connection-lifetime>18000000</proxool:maximum-connection-lifetime>
     <!-- 5 hours-->
       <proxool:simultaneous-build-throttle>5</proxool:simultaneous-build-throttle>
       <proxool:recently-started-threshold>40000</proxool:recently-started-threshold>
       <proxool:overload-without-refusal-lifetime>50000</proxool:overload-without-refusal-lifetime>
       <proxool:maximum-active-time>60000</proxool:maximum-active-time>
       <proxool:verbose>true</proxool:verbose>
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章