原文地址:http://blog.sina.com.cn/s/blog_7ffb8dd501019bon.html
一、Proxool連接池簡介及其配置屬性概述
目前是和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&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>