`
zhb870815
  • 浏览: 25401 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

浅析 jdbc 数据库连接池 druid & proxool

阅读更多
    很久没上来写点东西,正好这几天在测试一个数据库连接池。顺便上来MARK一下,露个脸啥的.......
    上周我们发生了新版上线以来的最大的一次故障,表现为数据库连接数暴增,所有的应用无法连接数据库,数据库服务器负载居高不下,最终导致数据库服务器宕机。经过了6个多小时的处理才慢慢的恢复过来。在这个故障中,现象是数据库服务器宕机了,但是真正导致此事故的原因并不是由于数据库本身造成的。而数据库服务器的宕机,也就让恢复的时间变的相对较长。于是领导要求无论在什么故障下,都要能让数据库正常提供服务,至少要保证能登陆进去进行一些操作。再根据最近的优化需求,应用层打算先从数据库连接池入手。
    我们现在使用的数据库连接池为proxool,这个连接池的性能和稳定性都是不错的,网上已经有很多关于此连接池的介绍,proxool广泛用于大型的WEB应用中,口碑不错。druid是阿里巴巴开源的一个项目,由温少等开发(什么?不认识?我也没见过!),wiki:http://code.alibabatech.com/wiki/display/Druid/Home
在这个WIKI中,文档中详细的介绍了关于druid dataSource的用法和性能测试。但是文档中没有包含与proxool中的测试。
    今天我们要做的事情是基于proxool+mysql以及druid+mysql的数据库连接池性能,稳定性,监控方面的比较与测试,由于是第一次接触此方面的东西进行测试,希望各位能指出不对的地方,感激不尽。借用网友的话:欢迎拍砖!具体的测试参数和代码将在文后给出。
一,性能测试
    1、循环100次单线程1000次取连接和关闭连接耗时。部分代码贴图
   
PoolTestInterface testPool = poolTestMap.get(poolKey);
		Connection conn = testPool.getConnection();
		try {
			try {
				PreparedStatement statement = conn.prepareStatement("select 1");
				ResultSet rs = statement.executeQuery();
				rs.close();
				statement.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} finally {
			if (conn != null){
				try {
					conn.close();
					conn = null;
				} catch (SQLException e) {
				}
			}
		}

   proxool执行1000次单线程开关连接任务平均耗时为:220 MS
   druid执行1000次单线程开关连接任务平均耗时为:72 MS

    测试数据要重点说明一下为什么要用平均值,两个连接池在初始化的时候消耗的时间都比较多,而且可以肯定的是连接池中初始化连接数越多,所消耗的时间也越多。(这就是为什么我们的应用的设置初始化数据库连接的时候要根据实际状况设置,设置的初始化连接数越多,启动就会越慢,但是启动之后第一批用户访问的速度会快一点。),所以用了一个100次的循环来取平均耗时,使得测试数据更具有参考性。

    2、10线程1000次获得连接并执行一次简单SQL查询的平均耗时对比
proxool全部执行完成平均耗时:13MS
druid全部执行完成平均耗时:10MS

    3、10线程10000次获得连接并执行一次简单SQL查询的平均耗时对比
proxool全部执行完成平均耗时:3MS
druid全部执行完成平均耗时:2MS

    4、50线程获得连接并执行一次简单SQL查询的耗时对比(连接池最大连接数10个)
druid和proxool全部报无法获取空闲连接,已经达到设置的最大连接数
在线程多,而最大连接数少的情况下,连接都不空闲,无法获得连接。

附:部分测试代码
获得不同连接池的接口

public interface PoolTestInterface {
	/**
	 * 获得数据库连接
	 * @return
	 */
	public Connection getConnection();
	/**
	 * 连接池的不同的标示
	 * @return
	 */
	public String getConnectionPoolKey();
}


//druid连接池实例
public class DruidPoolInstence extends AbstractPoolInstence {

	DruidDataSource dataSource = null;

	@Override
	public String getConnectionPoolKey() {
		return "druid";
	}

	@Override
	protected DataSource getDataSource() {
		if (dataSource == null) {
			dataSource = new DruidDataSource();
			dataSource.setMaxActive(100);
			dataSource.setMaxIdle(30);
			dataSource.setMinIdle(20);
			dataSource.setInitialSize(10);
			dataSource.setPoolPreparedStatements(true);
			dataSource.setTestOnBorrow(false);
			dataSource.setTestOnReturn(false);
			dataSource.setMinEvictableIdleTimeMillis(30);
			dataSource.setMaxWaitThreadCount(1000);
			dataSource.setDriverClassName("com.mysql.jdbc.Driver");
			dataSource.setUrl("jdbc:mysql://localhost:3306/lottery");
			dataSource.setUsername("root");
			dataSource.setPassword("root");
		}
		return dataSource;
	}
}


   
//proxool连接池实例
public class ProxoolInstence extends AbstractPoolInstence {

	ProxoolDataSource dataSource = null;

	@Override
	public String getConnectionPoolKey() {
		return "proxool";
	}

	@Override
	protected DataSource getDataSource() {
		if (dataSource == null) {
			dataSource = new ProxoolDataSource();
			dataSource.setDriver("com.mysql.jdbc.Driver");
			dataSource.setDriverUrl("jdbc:mysql://localhost:3306/lottery");
			dataSource.setUser("root");
			dataSource.setPassword("root");

			dataSource.setAlias("test_proxool");
			dataSource.setMaximumConnectionCount(100);
			dataSource.setMinimumConnectionCount(20);
			dataSource.setMaximumActiveTime(600000);
			dataSource.setHouseKeepingSleepTime(90000);
			dataSource.setSimultaneousBuildThrottle(20);
			dataSource.setPrototypeCount(20);
			dataSource.setTestBeforeUse(false);
			dataSource.setHouseKeepingTestSql("select 1 from dual");
		}
		return dataSource;
	}
}

下面的代码就是测试代码,写的不规范,见谅
public abstract class AbstractConnectionPoolTest {
	// 消耗时间:MS
	public static long cusTime = 0;
	// 线程个数
	static int threadNum = 10;
	// 循环次数
	static int forCount = 10;
	// 总共执行次数
	static int excuteCount = 0;
	
	static ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
	public static Map<String, PoolTestInterface> poolTestMap = new HashMap<String, PoolTestInterface>();
	public static final String DRUID = "druid";
	public static final String PROXOOL = "proxool";
	static {
		poolTestMap.put("druid", new DruidPoolInstence());
		poolTestMap.put("proxool", new ProxoolInstence());
	}
	
	public synchronized static void addCusTime(long time) {
		cusTime += time;
		excuteCount++;
		System.out.println("单次执行完成耗时:" + time);
		System.out.println("执行完成共耗时:" + cusTime);
		if (excuteCount == threadNum * forCount) {
			System.out.println("全部执行完成执行平均耗时:" + cusTime / excuteCount);
			executorService.shutdown();
		}
	}
}

public class OpenConnectionTest extends AbstractConnectionPoolTest {
	public static void openConnTest(String poolKey) {
		PoolTestInterface testPool = poolTestMap.get(poolKey);
		Connection conn = testPool.getConnection();
		try {
			try {
				PreparedStatement statement = conn.prepareStatement("select 1");
				ResultSet rs = statement.executeQuery();
				rs.close();
				statement.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} finally {
			if (conn != null)
				try {
					conn.close();
					conn = null;
				} catch (SQLException e) {
				}
		}
	}

	public static void main(String[] args) {
		Map<String, Long> timeMap = new HashMap<String, Long>();
		String poolKeyArr[] = { PROXOOL, DRUID };
		for (int j = 0; j < forCount; j++) {
			for (String poolKey : poolKeyArr) {
				try {
					long start = System.currentTimeMillis();
					System.out.println(poolKey + "单线程1000次开始执行");
					for (int i = 0; i < 1000; i++) {
						openConnTest(poolKey);
					}
					long end = System.currentTimeMillis();

					long t = end - start;
					Long tempT = timeMap.get(poolKey) == null ? 0l : timeMap
							.get(poolKey);
					timeMap.put(poolKey, tempT + t);
					System.out
							.println(poolKey + "单线程1000次执行结束" + (end - start));
				} catch (Exception e) {
					e.printStackTrace();
					continue;
				}
			}
		}

		for (String pk : poolKeyArr) {
			System.out.println(pk + "执行1000次单线程开关连接任务平均耗时为:" + timeMap.get(pk)
					/ forCount);
		}
	}
}



二,监控对比
    稍后呈现........






分享到:
评论
1 楼 q63176347 2016-04-15  
看了下,答案在表示druid性能实力碾压 proxool啊,怎么破,我还在用C3P0呢;

相关推荐

    Java-jdbc数据库连接池总结.doc

    Java JDBC 数据库连接池技术是Java应用程序访问数据库的关键优化手段,尤其在Web应用程序中,它解决了传统JDBC连接方式存在的效率低下和资源浪费问题。Java JDBC(Java Database Connectivity)是Java语言与各种...

    最新版阿里数据库连接池Druid-1.1.2.jar

    最新版阿里数据库连接池Druid-1.1.2.jar

    JDBC数据库连接池的简单实现.rar

    总结来说,JDBC数据库连接池如Druid的实现主要涉及以下几个步骤:引入依赖、配置连接池属性、在代码中使用连接池以及可选的监控和扩展。通过这些方式,我们可以有效地管理和优化数据库连接,提高应用的运行效率。

    jdbc数据库连接池工程文件

    **JDBC数据库连接池工程文件详解** 在Java开发中,JDBC(Java Database Connectivity)是用于与各种数据库交互的标准API。然而,频繁地创建和关闭数据库连接会消耗大量的系统资源,影响应用程序性能。为了解决这个...

    java数据库连接池Druid

    Druid是阿里巴巴开源的一款优秀的数据库连接池实现,它不仅提供了基本的连接池功能,还集成了监控、日志、SQL解析等高级特性。本篇文章将深入探讨Druid的核心特性和使用方法。 1. **简介** Druid是阿里巴巴在2010...

    jdbc数据库连接池

    ** JDBC数据库连接池详解 ** 在Java开发中,JDBC(Java Database Connectivity)是用于与数据库交互的标准API。然而,直接使用JDBC进行数据库操作可能会导致资源管理的问题,因为每次数据库连接的创建和关闭都会...

    JDBC&Druid数据库连接池

    "JDBC&Druid数据库连接池" JDBC(Java Database Connectivity)是一种Java API,用于连接和操作数据库。Druid是一个Java语言的数据库连接池,旨在提供高效、稳定、可靠的数据库连接服务。 JDBC基本概念 JDBC是一...

    最新版加注释通用JDBC数据库连接池

    本资源名为“最新版加注释通用JDBC数据库连接池”,显然它提供了一个带有详细注释的通用JDBC数据库连接池实现,这将有助于开发者理解和使用。这里我们将详细讲解数据库连接池的概念、工作原理以及如何使用。 **...

    数据库连接池druid-1.1.21.jar 和 配置文件druid.properties

    本主题将深入探讨数据库连接池Druid以及它的1.1.21版本,同时也会涉及如何配置其核心组件——`druid.properties`文件。 Druid是一个流行的Java数据库连接池实现,由阿里巴巴开发并开源。它不仅提供了数据库连接池的...

    mysql驱动数据库连接池 druid jar

    总结起来,MySQL JDBC驱动和Druid数据库连接池是Java开发中用于高效管理和使用MySQL数据库的关键组件。正确配置和使用它们,可以显著提升应用程序的稳定性和性能。在实际开发中,结合这两个工具,开发者可以构建出更...

    阿里巴巴数据库连接池druid及其源码

    **阿里巴巴数据库连接池Druid详解** Druid是阿里巴巴开源的一款高效、强大且可扩展的数据库连接池组件。作为Java世界中的优秀数据源管理工具,它不仅提供了基础的数据库连接池功能,还内置了丰富的监控和扩展特性,...

    数据库连接池druid,c3p0,jdbctemplate,jar包.rar

    数据库连接池jar包,包含c3p0、druidjar包和依赖jar包,c3p0通过配置文件xml或者properties读取连接对象 druid通过properties读取连接,使用springJDBC JdbcTempalte简化sql操作

    达梦7数据库连接池,jdbcDriver

    达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,达梦7数据库连接池,jdbcDriver,

    最新版druid 数据库连接池 druid-1.1.21.jar

    Druid是阿里巴巴开源的一个高效、强大的数据库连接池组件,它的全称是Dynamic Routing Data Source,即动态路由数据源。在Java Web开发中,数据库连接池扮演着至关重要的角色,它负责管理数据库连接,提高数据库操作...

    数据库连接池druid

    数据库连接池 druid-1.0.9数据库连接池技术,由阿里巴巴提供。使用步骤: 1.导入jar包:druid-1.0.9.jar 2.定义配置文件:druid.properties,可取任意名称,放任意路径

    Java_jdbc数据库连接池总结

    Java JDBC数据库连接池总结 Java JDBC(Java Database Connectivity)是Java语言访问数据库的标准接口,它允许应用程序通过编写Java代码来与各种数据库进行交互。在Web应用程序中,由于B/S架构的普及,Java JDBC...

    JDBC数据库连接池相关jar包

    本文将详细讲解标题中提到的几个关键组件:MySQL驱动包、C3P0数据库连接池、Druid数据库连接池以及Spring Template,这些都是Java Web开发中不可或缺的部分。 首先,我们来看MySQL驱动包。MySQL是广泛使用的开源...

    JDBC线程安全的Druid数据库连接池工具类

    JDBC工具类使用阿里巴巴的数据库连接池Druid,支持高并发,有多线程环境下的事务和查询测试。

    Java jdbc数据库连接池总结2

    4. **Druid**:阿里巴巴开源的数据库连接池,除了基础功能外,还提供了监控、日志、SQL解析等功能。 5. **Tomcat JDBC Pool**:Tomcat服务器自带的连接池,适合在Tomcat环境中使用。 ### 连接池的优点 1. **资源...

    druid1.2.8 下载 数据库连接池

    Druid是阿里巴巴开源的一个高性能、多功能的数据库连接池组件,它在Java开发中广泛应用于各种项目的数据库管理。在1.2.8版本中,Druid提供了一系列优化和改进,旨在提高数据库访问性能,增强监控能力,并简化数据库...

Global site tag (gtag.js) - Google Analytics