Proxool 0.9.1的配置與應用

火星人 @ 2014-03-09 , reply:0


  Proxool老牌的資料庫連接池了,褒貶不一,性能上還行.目前最新版本是0.9.1,相對之前版本的配置有些變動.這裡以MySQL5為例做一個簡單資料庫連接池配置.

  環境:

  MySQL5.x

  JDK1.5

  Proxool 0.9.1

  一、配置文件

  proxool.xml

  <?xml version="1.0" encoding="UTF-8"?>

  <something-else-entirely>

  <proxool>

  <alias>ds</alias>

  <!--數據源的別名-->

  <driver-url>jdbc:mysql://192.168.104.191:3306/testdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull</driver-url>

  <!--url連接串-->

  <driver-class>com.mysql.jdbc.Driver</driver-class>

  <!--驅動類-->

  <driver-properties>

  <property name="user" value="vcom"/>

  <!--用戶名-->

  <property name="password" value="vcom"/>

  <!--密碼-->

  </driver-properties>

  <!-- 是指在任一時刻,可以(同時)建立的最大連接數,也就是說,就是已經請求的、但還沒可用的新連接數量-->

  <simultaneous-build-throttle>10</simultaneous-build-throttle>

  <!--最大連接數(默認5個),超過了這個連接數,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定 -->

  <maximum-connection-count>100</maximum-connection-count>

  <!--最小連接數(默認2個)-->

  <minimum-connection-count>10</minimum-connection-count>

  <!--proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閑的連接就馬上回收,超時的銷毀 默認30秒-->

  <house-keeping-sleep-time>120000</house-keeping-sleep-time>

  <!--最少保持的空閑連接數(默認2個)-->

  <prototype-count>10</prototype-count>

  <!--在使用之前測試-->

  <test-before-use>true</test-before-use>

  <!--用於保持連接的測試語句 -->

  <house-keeping-test-sql>select 1</house-keeping-test-sql>

  </proxool>

  </something-else-entirely>

  粗體部分是變化部分,上面有詳細說明!

  二、測試類

  package lavasoft;

  import org.apache.commons.logging.Log;

  import org.apache.commons.logging.LogFactory;

  import org.logicalcobwebs.proxool.ProxoolException;

  import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;

  import java.io.FileNotFoundException;

  import java.io.IOException;

  import java.sql.*;

  import java.util.List;

  import java.util.Properties;

  /**

  * 簡單的JDBC工具類

  *

  * @author leizhimin 2009-11-23 17:35:26

  */

  public class MyDB {

  private static final Log log = LogFactory.getLog(MyDB.class);

  private static final boolean useDBPool = true; //是否使用資料庫連接池

  private static String dburl = null;

  private static String user = null;

  private static String password = null;

  private static Properties props = new Properties();

  static {

  init();

  }

  public static void init() {

  if (useDBPool) {

  try {

  JAXPConfigurator.configure("proxool.xml", false);

  // JAXPConfigurator.configure("src/proxool.xml", false);

  } catch (ProxoolException e) {

  e.printStackTrace();

  }

  return;

  }

  try {

  // props.load(new FileInputStream("/jdbc.properties"));

  props.load(MyDB.class.getResourceAsStream("/jdbc.properties"));

  } catch (IOException e) {

  log.error("#ERROR# :系統載入sysconfig.properties配置文件異常,請檢查!", e);

  }

  dburl = props.getProperty("jdbc.url");

  user = props.getProperty("jdbc.username").trim();

  password = props.getProperty("jdbc.password").trim();

  System.out.println(dburl);

  System.out.println(user);

  System.out.println(password);

  //註冊驅動類

  try {

  Class.forName(props.getProperty("jdbc.driver"));

  } catch (ClassNotFoundException e) {

  log.error("#ERROR# :載入資料庫驅動異常,請檢查!", e);

  throw new RuntimeException(e);

  }

  }

  public static void main(String[] args) throws FileNotFoundException {

  for (int i = 0; i < 5; i ) {

  Connection conn = getConnection();

  System.out.println(conn == null ? "沒連上" : "連上了");

  // System.out.println("--------");

  // closeConnection(conn);

  }

  }

  /**

  * 創建一個資料庫連接

  *

  * @return 一個資料庫連接

  */

  public static Connection getConnection() {

  Connection conn = null;

  //根據連接池配置創建資料庫連接

  if (useDBPool) {

  try {

  conn = DriverManager.getConnection("proxool.ds");

  } catch (SQLException e) {

  log.error("#ERROR# :無法從資料庫連接池獲取到資料庫連接!");

  throw new RuntimeException(e);

  }

  return conn;

  }

  //根據JDBC配置創建資料庫連接

  try {

  conn = DriverManager.getConnection(dburl, user, password);

  } catch (SQLException e) {

  log.error("#ERROR# :創建資料庫連接發生異常,請檢查!", e);

  throw new RuntimeException(e);

  }

  return conn;

  }

  /**

  * 在一個資料庫連接上執行一個靜態SQL語句查詢

  *

  * @param conn 資料庫連接

  * @param staticSql 靜態SQL語句字元串

  * @return 返回查詢結果集ResultSet對象

  */

  public static ResultSet executeQuery(Connection conn, String staticSql) {

  ResultSet rs = null;

  try {

  //創建執行SQL的對象

  Statement stmt = conn.createStatement();

  //執行SQL,並獲取返回結果

  rs = stmt.executeQuery(staticSql);

  } catch (SQLException e) {

  log.error("#ERROR# :執行SQL語句出錯,請檢查!n" staticSql, e);

  throw new RuntimeException(e);

  }

  return rs;

  }

  /**

  * 在一個資料庫連接上執行一個靜態SQL語句

  *

  * @param conn 資料庫連接

  * @param staticSql 靜態SQL語句字元串

  */

  public static void executeSQL(Connection conn, String staticSql) {

  try {

  //創建執行SQL的對象

  Statement stmt = conn.createStatement();

  //執行SQL,並獲取返回結果

  stmt.execute(staticSql);

  } catch (SQLException e) {

  log.error("#ERROR# :執行SQL語句出錯,請檢查!n" staticSql, e);

  throw new RuntimeException(e);

  }

  }

  /**

  * 在一個資料庫連接上執行一批靜態SQL語句

  *

  * @param conn 資料庫連接

  * @param sqlList 靜態SQL語句字元串集合

  */

  public static void executeBatchSQL(Connection conn, List<String> sqlList) {

  try {

  //創建執行SQL的對象

  Statement stmt = conn.createStatement();

  for (String sql : sqlList) {

  stmt.addBatch(sql);

  }

  //執行SQL,並獲取返回結果

  stmt.executeBatch();

  } catch (SQLException e) {

  log.error("#ERROR# :執行批量SQL語句出錯,請檢查!", e);

  }

  }

  public static void closeConnection(Connection conn) {

  if (conn == null) return;

  try {

  if (!conn.isClosed()) {

  //關閉資料庫連接

  conn.close();

  }

  } catch (SQLException e) {

  log.error("#ERROR# :關閉資料庫連接發生異常,請檢查!", e);

  throw new RuntimeException(e);

  }

  }

  }

  運行結果:

  [INFO] 2010-02-25 13:05:20 [org.logicalcobwebs.proxool.ProxoolFacade] Proxool 0.9.1 (23-Aug-2008 11:10)

  連上了

  連上了

  連上了

  連上了

  連上了

  [INFO] 2010-02-25 13:05:22 [org.logicalcobwebs.proxool.ds] Shutting down 'ds' pool immediately [Shutdown Hook]

  [INFO] 2010-02-25 13:05:22 [org.logicalcobwebs.proxool.ConnectionPool] Waiting until Thu Feb 25 13:05:22 CST 2010 for all connections to become inactive (active count is 5).

  [WARN] 2010-02-25 13:05:22 [org.logicalcobwebs.proxool.ConnectionPool] Shutdown waited for 0 milliseconds for all the connections to become inactive but the active count is still 5. Shutting down anyway.

  [INFO] 2010-02-25 13:05:22 [org.logicalcobwebs.proxool.PrototyperController] Stopping Prototyper thread

  [INFO] 2010-02-25 13:05:22 [org.logicalcobwebs.proxool.HouseKeeperController] Stopping HouseKeeper thread

  Process finished with exit code 0

  Proxool提供的配置方式很多,這裡進選擇最常用的xml方式,另外的方式也很簡單,可以參看官方文檔:

  http://proxool.sourceforge.net/index.html

  http://proxool.sourceforge.net/configure.html

  三、Proxool很扯蛋的問題----找不到配置文件

  proxool的配置文件載入做的比較差勁,通過兩個類來載入配置文件:

  org.logicalcobwebs.proxool.configuration.PropertyConfigurator

  org.logicalcobwebs.proxool.configuration.ServletConfigurator

  org.logicalcobwebs.proxool.configuration.XMLConfigurator

  org.logicalcobwebs.proxool.configuration.JAXPConfigurator

  org.logicalcobwebs.proxool.configuration.AvalonConfigurator

  這幾個類載入配置文件時候,常常會提示找不到配置文件,其原因是proxool在讀取CLASSPATH下路徑有問題,經常看到一種情況就是,在開發環境IDE環境下面測試通過,在打包后脫離IDE環境獨立運行時候就提示找不到配置文件.這裡有一個簡單的解決方法就是不要使用文件名指定配置文件,而是通過讀取CLASSPATH下的配置文件流,形成位元組流傳遞給配置工具類來實現.比如:

  public static void init() {

  //初始化資料庫連接配置參數

  InputStream in = MyDB.class.getResourceAsStream("/proxool.xml");

  Reader reader = null;

  try {

  reader = new InputStreamReader(in, "GBK");

  } catch (UnsupportedEncodingException e) {

  e.printStackTrace();

  }

  try {

  JAXPConfigurator.configure(reader, false);

  } catch (ProxoolException e) {

  e.printStackTrace();

  }

  }

  在初始化Proxool環境的時候,千萬不要把第二個驗證參數設置為true,否則老提示驗證失敗,但是配置文件語法什麼都沒錯,這個問題我僅僅發現了,但沒找到根本原因,解決辦事是只需要將其設置為false就行.

  本文出自 「熔 岩」 博客,請務必保留此出處http://lavasoft.blog.51cto.com/62575/278521





[火星人 via ] Proxool 0.9.1的配置與應用已經有274次圍觀

http://www.coctec.com/docs/java/show-post-60578.html