`

项目中用到的Proxool0.9.1数据连接池配置实践

阅读更多

1:先是配置文件:

<?xml version="1.0" encoding="gb2312"?>
<!-- the proxool configuration can be embedded within your own application's.
	Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
	<proxool>
		<alias>example</alias>
		<driver-url>
			jdbc:oracle:thin:@*.*.*.*:1521:****
		</driver-url>
		<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
		<driver-properties>
			<property name="user" value="*****" />
			<property name="password" value="*****" />
		</driver-properties>
		<!--最大连接数(默认5个),超过了这个连接数,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定 -->
		<maximum-connection-count>20</maximum-connection-count>
		<!--最小连接数(默认2个,包含活动的和空闲的)-->
		<minimum-connection-count>4</minimum-connection-count>
		<!--proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒-->
		<house-keeping-sleep-time>30000</house-keeping-sleep-time>
		<!--没有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受-->
		<!-- maximum-new-connections不被推荐使用了,所以用simultaneous-build-throttle来代替了 -->
		<simultaneous-build-throttle>15</simultaneous-build-throttle>
		<!--maximum-new-connections>10</maximum-new-connections-->
		<!--最少保持的空闲连接数(默认2个)-->
		<prototype-count>2</prototype-count>
		<!-- maximum-active-time缺省5minutes 172800000毫秒=48小时-->
		<maximum-active-time>172800000</maximum-active-time>
		<!-- maximum-connection-lifetime缺省4hours 180000000毫秒=50小时-->
		<maximum-connection-lifetime>180000000</maximum-connection-lifetime>
		<!--在使用之前测试-->
		<test-before-use>false</test-before-use>
		<!--用于保持连接的测试语句 -->
		<!-- house-keeping-test-sql>
			select sysdate from dual
		</house-keeping-test-sql -->
		<!-- 是否监控sql信息 -->
		<trace>true</trace>
		<!-- statistics>10s,1m</statistics -->
		<!-- statistics-log-level>DEBUG</statistics-log-level -->
		
	</proxool>
</something-else-entirely>

 

 注释:(以上的数据连接IP和用户名密码根据自己的实际情况填写)

      配置文件里的两行

<!-- maximum-active-time缺省5minutes 172800000毫秒=48小时-->
<maximum-active-time>172800000</maximum-active-time>
<!-- maximum-connection-lifetime缺省4hours 180000000毫秒=50小时-->
<maximum-connection-lifetime>180000000</maximum-connection-lifetime>

第一个48小时的是设置连接活动的时间,即:你的sql或存储过程执行的时间,估算一下你的应用中的sql或存储过程最长的执行时间a,将这个值设为大于a就行了,这是项目中实际发现的问题经验,我有个sql执行时间超过了5分钟,而原来没有设置这个值,缺省为5分钟,所以我的应用刚起来没问题,跑一段时间,跑到这个sql时执行了一段时间后台就报:

java.sql.SQLException: Couldn't perform the operation prepareStatement: You can't perform any operations on this connection. It has been automatically closed by Proxool for some reason (see logs).

这个错误,后来去官方网页查看Properties发现,如果超过这个值,proxool就会自动kill掉这个连接。

      第二个50个小时是设置连接的寿命,这个值理论上应该大于连接的活动时间限制,不然活动时间限制就没有意义了,所以设为了50个小时

 

2:连接类

 

package com.ai.dyjf.base;

import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.logicalcobwebs.proxool.ConnectionInfoIF;
import org.logicalcobwebs.proxool.ConnectionPoolDefinitionIF;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.ProxoolFacade;
import org.logicalcobwebs.proxool.admin.SnapshotIF;
import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;
import org.xml.sax.InputSource;

import com.toolkit.my.db.DBAException;
import com.toolkit.my.db.base.IDBConnectionPool;

public class CCConnectionPoolUtil implements IDBConnectionPool{
	private static int activeCount = 0;//当前连接数
	static {
		try {
			JAXPConfigurator.configure(new InputSource(CCConnectionPoolUtil.class.getResourceAsStream("proxoolCC.xml")),
					false);
		} catch (ProxoolException e) {
			System.out
					.println("没有找到proxool的配置文件,请查看/src/com/ai/dyjf/base/proxoolCC.xml是否存在!");
			e.printStackTrace();
		}
	}

	/**
	 * 测试用的获取数据库连接
	 * @return
	 */
	public Connection getConnectionFromPool() {
		
		Connection conn = null;
//		// 1:注册驱动类,这次这个驱动已经不是Oracle的驱动了,是Proxool专用的驱动
//		try {
//			Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
//			// 2:创建数据库连接,这个参数是一个字符串,是数据源的别名,在配置文件中配置的timalias,参数格式为:proxool.数据源的别名
//			conn = DriverManager.getConnection("proxool.example");
//			ConnectionPoolDefinitionIF cpd =ProxoolFacade.getConnectionPoolDefinition("example");
//			SnapshotIF snapshotIF=ProxoolFacade.getSnapshot("example", true);
//			int curActiveCount = snapshotIF.getActiveConnectionCount();// 获得活动(正在使用的busy)连接数
//            if (curActiveCount != activeCount)// 当活动连接数变化时输出信息
//            { 
//            	System.out.println("activeCount:"+activeCount);
//            	FileWriter fw=null;
//            	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            	int availableCount = snapshotIF.getAvailableConnectionCount();// 获得可得到的(空闲的free)连接数
//                int maxCount = snapshotIF.getMaximumConnectionCount();// 获得总连接数(最大的)
//                int offlineCount=snapshotIF.getOfflineConnectionCount();//获得不在线的连接数(释放的)
//                long refusedCount=snapshotIF.getRefusedCount();//How many connections have been refused since the pool started
//                long servedCount=snapshotIF.getServedCount();//How many connections have been served since the pool started
//                
//                
//                Date snapshotDate=snapshotIF.getSnapshotDate();
//                ConnectionInfoIF[] connIF=snapshotIF.getConnectionInfos();
//                try {
//					fw=new FileWriter("proxoolCC.log",true);
//					fw.write("\n\n----------------连接数信息------------------\n");
//					fw.write("监控时间:"+sdf.format(snapshotDate)+"\n");
//					fw.write("busy连接数:"+curActiveCount+"\n");
//					fw.write("free连接数:"+availableCount+"\n");
//					fw.write("max连接数:"+maxCount+"\n");
//					fw.write("offlineCount连接数:"+offlineCount+"\n");
//					fw.write("refusedCount连接数:"+refusedCount+"\n");
//					fw.write("servedCount连接数:"+servedCount+"\n");
//					fw.write("----------------连接信息-----------------\n");
//					for(int i=0;i<connIF.length;i++){
//						ConnectionInfoIF connInfo=connIF[i];
//						fw.write("ConnectionId号:"+connInfo.getId()+"\n");
//						fw.write("Connection初始化时间:"+sdf.format(new Date(connInfo.getBirthTime()))+"\n");
//						fw.write("Connection年龄(mis):"+connInfo.getAge()+"\n");
//						fw.write("Connection状态(active-2;available-1;null-0;offline-3):"+connInfo.getStatus()+"\n");
//						fw.write("Connection最后一次活动开始时间:"+sdf.format(new Date(connInfo.getTimeLastStartActive()))+"\n");
//						fw.write("Connection最后一次活动结束时间:"+sdf.format(new Date(connInfo.getTimeLastStopActive()))+"\n");
//						fw.write("Connection最后一次活动占用时长(mis):"+(connInfo.getTimeLastStopActive()-connInfo.getTimeLastStartActive())+"\n");
//						String[] sqlCallsStrs=connInfo.getSqlCalls();
//						for(int j=0;i<sqlCallsStrs.length;j++){
//							fw.write("---------该连接执行的sql语句----------");
//							fw.write(sqlCallsStrs[j]);
//							fw.write("-----------------------------------");
//						}
//						
//					}
//					activeCount = curActiveCount;
//				} catch (IOException e) {
//					e.printStackTrace();
//				}finally{
//					if(null!=fw){
//						try {fw.close();} catch (IOException e) {e.printStackTrace();}
//					}
//				}
////            	System.out.println("----------------------------------");
////                System.out.println("监控时间:"+new SimpleDateFormat("yyyy-MM-dd HH24:mm:ss").format(snapshotDate));
////                System.out.println("busy连接数:"+curActiveCount);
////                System.out.println("free连接数:"+availableCount);
////                System.out.println("max连接数:"+maxCount);
////                System.out.println("offlineCount连接数:"+offlineCount);
////                System.out.println("refusedCount连接数:"+refusedCount);
////                System.out.println("servedCount连接数:"+servedCount);
////				  System.out.println("trace:"+cpd.isTrace());
////				  System.out.println("trace:"+cpd.getStatisticsLogLevel());
//////                System.out.println(curActiveCount + "(active)  " + availableCount + "(available)  " + maxCount + "(max)");
////                System.out.println("----------------------------------"); 
////                activeCount = curActiveCount;
//            }
//
//		} catch (ClassNotFoundException e) {
//			e.printStackTrace();
//		} catch (SQLException e) {
//			e.printStackTrace();
//		} catch (ProxoolException e) {
//			e.printStackTrace();
//		}
		return conn;
	}
	
	/**
	 * 关闭数据库连接
	 * @param conn
	 */
	public void releaseConnection(Connection conn){
		try {
			//关闭数据库连接
			// Check to see we actually got a connection before we
			// attempt to close it.
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void close() throws DBAException {
		
	}
/**
 * 真正业务调用的连接
 */
	public Connection fetchConnection() throws DBAException {
		Connection conn = null;
		// 1:注册驱动类,这次这个驱动已经不是Oracle的驱动了,是Proxool专用的驱动
		try {
			Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
			// 2:创建数据库连接,这个参数是一个字符串,是数据源的别名,在配置文件中配置的timalias,参数格式为:proxool.数据源的别名
			conn = DriverManager.getConnection("proxool.example");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
}

 

 

 注释:

       上面getConnectionFromPool() 这个方法是自己测试连接的方法,自己可以根据实际情况查看连接池的状态

 

另:如果是java应用使用Proxool则需要自己写 单例连接池获取类 实现,并保证连 该获取类的生命周期不销毁,

比如可以写监听类(用死循环实现),或是用定时任务TimeTask实现定时类,在定时类里去连接。总之就是要保证这个java应用的main不会结束,要保证连接池类的生命周期不被销毁并保持单例.

 

下面是个简单的提示类:

public class SysUtil {

	private IDBConnectionPool dbConnectionPool;
	private IConfigReader configReader;
	private ILogger logger;
	
	private int maxLogLevel = 0;
	private boolean systemOut = false;
	
	private static SysUtil _inst = null;
	
	static public SysUtil instance(){
		if(_inst == null){
			_inst = new SysUtil();
		}
		return _inst;
	}
	
	private SysUtil(){
		init();
	}
	 
	private void init(){
		try{
			configReader = new PropertiesConfig("config.txt");
//			dbConnectionPool = new NoConnectionPool(configReader.getValue("DBDirver"),configReader.getValue("DBUrl")
//				,configReader.getValue("DBUser"),configReader.getValue("DBPass"));
//			修改了通过连接池的实现
			dbConnectionPool=new CCConnectionPoolUtil();
			logger = new DBTableLogger(dbConnectionPool);
			
			((ChainLogger)logger).setNextLogger(new Log4jLogger("log4j.properties",""));
//			这里传true才能正确解释,传false感觉没道理
			((ChainLogger)logger).setOnlyOnError(true);
		
			maxLogLevel = Integer.parseInt(configReader.getValue("MaxLogLevel"));
			systemOut = configReader.getValue("SYSTEMOUT").toUpperCase()=="TRUE"?true:false;
		}catch(ConfigException ce){
			ce.printStackTrace();
			throw new RuntimeException("SysUtil初始化失败!"+ce.getMessage(),ce);
		}
	}
	
	public String getConfigValue(String key) throws ConfigException{
		return configReader.getValue(key);
	}
	
	public Connection fetchConnection() throws DBAException{
		return dbConnectionPool.fetchConnection();
	}
	
	public void releaseConnection(Connection connection) throws DBAException{
		dbConnectionPool.releaseConnection(connection);
	}
}

 

只看上面类的部分代码,这个类就是用来从 CCConnectionPoolUtil 类里去连接的单例工具类

 

然后你可以在你的TimerTask里用这个工具类来取数据库连接实现逻辑,或这是你的不会结束的main里调用这个工具类来取数据库连接. 例如main里调用task的start,或是mian里用for(;;){这里分线程去做业务逻辑;}

 

 

如果是在web应用中使用Proxool则网上有很多怎么和web.xml或是spring配置结合的例子,这里就不在概述了!

 

 

 

3
0
分享到:
评论

相关推荐

    proxool-0.9.1.jar proxool_cglib-0.9.1.jar

    proxool-0.9.1.jar proxool_cglib-0.9.1.jar 用于连接池的配置

    struts2.2.3+spring2.5.6+hibernate3.2+proxool0.9.1

    struts2.2.3+spring2.5.6+hibernate3.2+proxool0.9.1 proxool数据库连接池例子 0资源下载

    proxool-0.9.1 jar;proxool-cglib.jar;

    proxool-0.9.1 jar;proxool-cglib.jar; 数据连接池

    proxool连接池用户名密码加密

    proxool 数据库连接池用户名、密码加密处理,文件里面包含可直接使用加密的jar以及相关使用说明。

    proxool-0.9.1源码下载

    proxool连接池0.9.1版本的源码,可供大家修改

    proxool-0.9.1.jar

    proxool-0.9.1.jar包是一个数据库连接池包,最新版解决前几个版本里在二次关闭一个rs集的时候警告等一些bug。proxool-0.9.1.jar监控在对中文监控出现乱码情况做了更改。具体是对org.logicalcobwebs.proxool.admin....

    proxool_0.9.1

    亲测可用。 此包 包括 proxool.0.9.1.jar proxool_cgilib.0.9.1.jarg两个JAR包,主要用于需要解决连接池监控中文问题!!!

    利用hibernate+spring配置proxool连接池连接Access数据库

    proxool-0.9.1(my).jar 包是我修改了proxool-0.9.1后的jar包,修改后可以完全支持spring配置,并添加了charSet配置属性,用于配置数据库链接的设置默认字符集,并且解决了proxool数据库连接池报如下错误的问题:...

    proxool-0.9.1.tar.gz

    proxool-0.9.1.tar.gz ,java版开源连接池,短小精悍

    proxool-0.9.1.jar commons-logging.jar

    proxool数据库连接池组建jar包 包括proxool-0.9.1.jar和commons-logging.jar两个文件

    JAVA数据库连接池proxool

    包含 proxool-cglib.jar proxool-0.9.1.jar 将数据库的连接交给连接池处理,方便,高效

    proxool-0.9.1.zip

    proxool 连接池 开发包下载,内有api文档说明。

    proxool bug修复版jar

    proxool用于spring,hibernate,struts集成数据库连接稳定版,修复proxool内部BUG

    proxool+mysql+tomcat连接池所需jar包

    下载包中包括 mysql-connector-java-5.1.7-bin.jar proxool-0.9.1.jar proxool-cglib.jar 解压密码为www.ablanxue.com

    proxool-0.9.1.2

    5.修正了ProxoolDataSource这个bean在spring配置中几个property不正确的问题。 houseKeepingSleepTime maximumConnectionLifetime overloadWithoutRefusalLifetime recentlyStartedThreshold 这几个参数设置...

    proxool-0.9.1.jar DecUtil.java

    proxool是个很好的开源连接池。但配置文件中的用户和密码却是明文存储的,如果对系统安全有较高的要求,使用时就麻烦了。文件做了些小小的改动,现在proxool配置文件中用户和密码可以使用密文存储了,同时明文的也...

    Proxool-0.9.1

    proxool.0.9.1基础上做了修改。 改jar名称为:proxool-0.9.1.1,主要修改为以下3点: 1.解决不能Unregister jdbc driver的内存泄露问题。 十二月 02, 2013 8:19:43 上午 org.apache.catalina.loader....

    自定义PROXOOL监听器整合SSH框架

    1、proxool官网,下载最新的proxool-...3、创建自定义数据库连接池监听 4、整合Struts2、Spring和proxool,配置Web服务启动配置文件[web.xml] 5、整合Spring和proxool,配置应用上下文配置文件[applicationContext.xml]

Global site tag (gtag.js) - Google Analytics