技术开发 频道

数据库连接池Clearpool功能和配置详解

  【IT168 资讯】clearpool的maven项目托管在https://github.com/xionghuiCoder/clearpool,同时也可以在http://www.oschina.net/p/clearpool上了解它的简单介绍。

  首先大家可能会问:现在在开源社区已经有了很多数据库连接池:c3p0、proxool、dbcp、bonecp、druid和tomcat_jdbc等,我们还需要其它的连接池么?我要说的是上面这些连接池都非常优秀,并且各自都有自己优点:比如高并发时druid和tomcat_jdbc完美的性能,再比如proxool和druid的监控功能;然而它们并不是完美的,比如性能是否还能再提升、如果管理分布式数据库、如何支持分布式事务。好的,下面就来详细介绍下Clearpool以及它是如何支持这些功能的。

  1、如何使用Clearpool

  Clearpool提供的入口类为ClearPoolDataSource.java,它支持两种配置方法:配置xml、ioc注入(或者编程实现):xml的详细配置信息请参考https://github.com/xionghuiCoder/clearpool/blob/master/src/main/java/org/opensource/clearpool/configuration/clearpool-describe.xml。这里说下Clearpool和其它数据库池的不同的地方:1)它不支持最小连接池数(min-pool-size),区而代之的是核心连接池数(core-pool-size);2)它不提供返回真实连接的方法,ClearPoolDataSource.java的getConnection()方法返回的是数据库连接的代理,除非利用反射机制(不建议这么做),不然不能真正操作数据库连接;3)它不会在获取连接时测试连接是否有效,因为这个操作可能会非常耗时,而它并不提供返回真实连接的方法,所以就屏蔽了和数据库连接的直接通信,所以不用担心会不小心关闭连接等意外情况。

  2、如何配置DataSource

  Clearpool提供三种数据源配置方式:1)配置JDBC,2)配置jndi,3)如果自定义的DataSource,可以使用DataSourceHolder.java的setDataSourceMap方法来配置。

  如果需要支持分布式事务需要配置XADataSource或者支持XA协议的JDBC。

  3、Clearpool的性能

  根据测试结果:druid和tomcat_jdbc的性能是非常优秀的,在某些高并发的情况下它俩的性能要比其它的连接池高上十倍甚至是几十倍。然而他们无一例外地都使用了连接池锁(ps:proxool未使用锁,在高并发的情况下获取连接会导致ArrayIndexOutOfBoundsException),那么如果我们不使用锁的话那岂不是肯定能提高性能?是的,这是当然。Clearpool并没有使用任何锁机制,而且不会导致任何数据越界异常,它的秘诀就是使用Atomic操作代替了锁,详细的实现清参考类https://github.com/xionghuiCoder/clearpool/blob/master/src/main/java/org/opensource/clearpool/core/chain/AtomicSingleChain.java。然而AtomicSingleChain.java使用了sun.misc.Unsafe.java,或许比较保守的你会说这是一种冒险的做法,是的,或许以后oracle会抛弃Unsafe.java,不过没关系,这是我们可以使用它的替身LockSingleChain.java,这是一个普通的、使用锁的连接池实现。下面来看看Clearpool和druid、tomcat_jdbc的性能比较结果(最大连接数为50、最小连接数为20、线程数为100):

数据库连接池Clearpool功能和配置详解

  上图的测试结果来自于:https://github.com/xionghuiCoder/clearpool/blob/master/src/test/java/org/opensource/clearpool/CompareWithWonderfulPoolCase.java,如果想了解和其它数据库的性能比较结果请参考测试类:https://github.com/xionghuiCoder/clearpool/blob/master/src/test/java/org/opensource/clearpool/CompareWithPopularPoolCase.java

  上图比较的是高并发下“获取连接”时的性能,如果需要测试高并发下的DML,Clearpool的性能就和druid、tomcat_jdbc差不多了,原因在于Clearpool使用动态代理生成Statement代理,动态代理生成字节码时会比较耗时,而生成的字节码会作为WeakReference缓存,而高并发下会多次启动gc,从而会多次回收并多次生成Statement代理的字节码,所以就影响了测试结果(详细情况请参见JDK的java.lang.reflect.Proxy.java的源码)。而druid和tomcat_jdbc使用的是普通的静态代理,所以没有这个问题。Clearpool使用动态代理的原因主要是为了减少代码量(我是个懒人),如果使用静态代理,至少需要实现三个代理类(Statement、PreparedStatement和CallableStatement)以及它们的所有方法。而使用动态代理只需要一个handler(https://github.com/xionghuiCoder/clearpool/blob/master/src/main/java/org/opensource/clearpool/datasource/proxy/dynamic/StatementHandler.java)就足够了。

  4、管理分布式数据库池和JTA

  Clearpool可以管理分布式数据库,配置分布式连接池时我们需要做的只是配置多个<distribute-url>标签(xml配置)或者初始化多个连接池(IOC或者编程实现)。Clearpool会根据配置自动管理所有连接池:比如多余空闲连接的回收、无效连接的重置、数据库池的监控等等。Clearpool还提供了支持JTA的入口类:UserTransactionImpl.java,我们可以像下面这样简单地使用分布式事务(con1和con2取自数据库连接池):

  UserTransaction tx = new UserTransactionImpl(); Statement st1 = con1.createStatement(); Statement st2 = con2.createStatement(); tx.begin(); try{ st1 .execute(“insert**”); st2 .execute(“update**”); tx.commit(); }catch(Throwable t){ ts.roolback(); }

  5、如何监控数据库连接池

  如果想要监控数据库连接池,则需要配置<console>(xml配置)或者设置ClearPoolDataSource的Console,我们可以通过<console>的<port>配置端口、通过<console>的<port>的<security>配置用户名和密码,详细监控功能可参考测试用例https://github.com/xionghuiCoder/clearpool/blob/master/src/test/java/org/opensource/clearpool/UniqueFunctionCase.java。下面是监控页面的部分截图:

数据库连接池Clearpool功能和配置详解

  如果需要打印sql,则需要配置<show-sql>为true或者设置ClearPoolDataSource的setShowSql(true)方法,同时需要启用日志功能(classpath中加入commons-logging.jar即可),下图是查询的代码以及打印sql的截图:

  PreparedStatement s = conn.prepareStatement("select 1 from ?"); s.setString(1, "hello"); s.execute(); s.close();

数据库连接池Clearpool功能和配置详解

  6、其它

  Clearpool本身不提供log功能,但也可以打印日志,它并不像proxool那样强制把commons-logging.jar的代码内嵌入proxool.jar,而是可以和commons-logging无缝衔接,如果想要打印日志只需要引入commons-logging.jar即可。好吧,“Clearpool并不生产日志,它只是日志的搬运工”。Clearpool代码量十分地少,jar包只有100KB左右,非常易于使用和阅读,相信你能非常快地使用和修改它。

  如果需要使用Clearpool,又不想下载github上的maven项目,请留言告诉我,我会发给你它的jar文件和源码。

  PS:Clearpool是在1.7版本的编译器和jdk下开发和编译的,所以需要1.7版本的JDK和编译器来运行它。

0
相关文章