`
g21121
  • 浏览: 685180 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

连接池c3p0 ,Proxool ,Druid ,Tomcat Jdbc Pool对比测试

 
阅读更多

        这次所要做的测试是比较几种我们常用的数据库连接池的性能,他们分别是:c3p0 ,Proxool ,Druid ,Tomcat Jdbc Pool这四种,测试将采用统一的参数配置力求比较“公平”的体现统一水平下几种连接池的不同,有网友回复说测试不公平会互相干扰,那我就把代码分开,代码是死的人是活的,做事情不动脑只能吃别人剩下的,世界上没有绝对公平的事情,我在此只提供了一个思路,更多的测试还需要你自己去完成。

 

        1.创建类TestDAO,封装统一的查询方法 :

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDAO {

    private final static String sql = "SELECT * FROM USER u WHERE u.USR_ID=9999";

    public void query(Connection conn) {
        try {
            Statement st = conn.createStatement();
            ResultSet result = st.executeQuery(sql);
            result.close();
            st.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

 

 

        2.创建测试类TestMain,其中包含:统一参数配置属性、获取各种连接池数据源方法、各种数据源调用方法等,下面分别是各种数据源的测试Main方法,开始测试之前做100次查询操作以初始化连接池并起到稳定测试结果作用:

 

        (1)c3p0测试代码:

import java.beans.PropertyVetoException;
import java.io.IOException;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3p0Test {

    // 数据库驱动名称
    final static String driver = "com.mysql.jdbc.Driver";
    // 数据库连接地址
    final static String jdbcUrl = "jdbc:mysql://192.168.0.1:3306/test";
    // 数据库用户名
    final static String user = "dba";
    // 数据库密码
    final static String passwd = "dba";
    // 连接池初始化大小
    final static int initialSize = 5;
    // 连接池最小空闲
    final static int minPoolSize = 10;
    // 连接池最大连接数量
    final static int maxPoolSize = 50;
    // 最小逐出时间,100秒
    final static int maxIdleTime = 100000;
    // 连接失败重试次数
    final static int retryAttempts = 10;
    // 当连接池连接耗尽时获取连接数
    final static int acquireIncrement = 5;
    // c3p0数据源
    final static ComboPooledDataSource c3p0DataSource = getC3p0DataSource();

    // 查询次数
    final static int count = 10;

    /**
     * 测试方式: 每种数据源配置信息尽量相同,以求结果更加准确
     * 每种数据源做10次、100次、500次、1000次、2000次、4000次、8000次查询操作 每种查询重复100次,查看100次执行时间的波动图
     * @param args
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, SQLException {

        TestDAO testDAO = new TestDAO();
        System.out.println("查询次数为:" + count);
        System.out.println();
        System.out.println("==========================c3p0 测试开始==========================");
        // 测试c3p0
        for (int i = 0; i < 100; i++) {
            queryC3p0(testDAO, c3p0DataSource, count);
        }
        System.out.println("==========================c3p0 测试结束==========================");
    }

    /**
     * c3p0测试
     * @param testDAO
     * @param ds
     * @param count
     * @throws SQLException
     */
    public static void queryC3p0(TestDAO testDAO, ComboPooledDataSource ds, int count) throws SQLException {
        // 查询100次以初始化连接池
        for (int i = 0; i < 100; i++) {
            testDAO.query(ds.getConnection());
        }
        // 开始时间
        long startMillis = System.currentTimeMillis();
        // 循环查询
        for (int i = 0; i < count; i++) {
            testDAO.query(ds.getConnection());
        }
        // 结束时间
        long endMillis = System.currentTimeMillis();
        // 输出结束时间
        System.out.println(endMillis - startMillis);
    }

    /**
     * 获取c3p0数据源
     * @throws PropertyVetoException
     */
    public static ComboPooledDataSource getC3p0DataSource() {
        // 设置参数
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        try {
            cpds.setDriverClass(driver);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        cpds.setJdbcUrl(jdbcUrl);
        cpds.setUser(user);
        cpds.setPassword(passwd);
        cpds.setInitialPoolSize(initialSize);
        cpds.setMinPoolSize(minPoolSize);
        cpds.setMaxPoolSize(maxPoolSize);
        cpds.setMaxIdleTime(maxIdleTime);
        cpds.setAcquireRetryAttempts(retryAttempts);
        cpds.setAcquireIncrement(acquireIncrement);
        cpds.setTestConnectionOnCheckin(false);
        cpds.setTestConnectionOnCheckout(false);
        return cpds;
    }
}

 

 

        (2)Proxool测试代码: 

import java.io.IOException;
import java.sql.SQLException;
import org.logicalcobwebs.proxool.ProxoolDataSource;

public class ProxoolTest {

    // 数据库驱动名称
    final static String driver = "com.mysql.jdbc.Driver";
    // 数据库连接地址
    final static String jdbcUrl = "jdbc:mysql://192.168.0.1:3306/test";
    // 数据库用户名
    final static String user = "dba";
    // 数据库密码
    final static String passwd = "dba";
    // 连接池初始化大小
    final static int initialSize = 5;
    // 连接池最小空闲
    final static int minPoolSize = 10;
    // 连接池最大连接数量
    final static int maxPoolSize = 50;
    // 最小逐出时间,100秒
    final static int maxIdleTime = 100000;
    // 连接失败重试次数
    final static int retryAttempts = 10;
    // 当连接池连接耗尽时获取连接数
    final static int acquireIncrement = 5;
    // Proxool数据源
    final static ProxoolDataSource proxoolDataSource = getProxoolDataSource();
    // 查询次数
    final static int count = 10;

    /**
     * 测试方式: 每种数据源配置信息尽量相同,以求结果更加准确
     * 每种数据源做10次、100次、500次、1000次、2000次、4000次、8000次查询操作 每种查询重复100次,查看100次执行时间的波动图
     * @param args
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, SQLException {

        TestDAO testDAO = new TestDAO();
        System.out.println("查询次数为:" + count);
        System.out.println();
        System.out.println("==========================Proxool 测试开始==========================");
        // 测试Proxool
        for (int i = 0; i < 100; i++) {
            queryProxxool(testDAO, proxoolDataSource, count);
        }
        System.out.println("==========================Proxool 测试结束==========================");
    }

    /**
     * Proxxool测试
     * @param testDAO
     * @param ds
     * @param count
     * @throws SQLException
     */
    public static void queryProxxool(TestDAO testDAO, ProxoolDataSource ds, int count) throws SQLException {
        // 查询100次以初始化连接池
        for (int i = 0; i < 100; i++) {
            testDAO.query(ds.getConnection());
        }
        // 开始时间
        long startMillis = System.currentTimeMillis();
        // 循环查询
        for (int i = 0; i < count; i++) {
            testDAO.query(ds.getConnection());
        }
        // 结束时间
        long endMillis = System.currentTimeMillis();
        // 输出结束时间
        System.out.println(endMillis - startMillis);
    }

    /**
     * 获取Proxool数据源
     * @return
     */
    public static ProxoolDataSource getProxoolDataSource() {
        ProxoolDataSource pds = new ProxoolDataSource();
        pds.setAlias("mysql");
        pds.setUser(user);
        pds.setPassword(passwd);
        pds.setDriverUrl(jdbcUrl);
        pds.setDriver(driver);
        pds.setMaximumActiveTime(maxIdleTime);
        pds.setMaximumConnectionCount(maxPoolSize);
        pds.setMinimumConnectionCount(initialSize);
        pds.setPrototypeCount(minPoolSize);
        pds.setTestBeforeUse(false);
        pds.setTestAfterUse(false);
        return pds;
    }

}

 

 

        (3)Druid测试代码:

import java.io.IOException;
import java.sql.SQLException;
import com.alibaba.druid.pool.DruidDataSource;

public class DruidTest {

    // 数据库驱动名称
    final static String driver = "com.mysql.jdbc.Driver";
    // 数据库连接地址
    final static String jdbcUrl = "jdbc:mysql://192.168.0.1:3306/test";
    // 数据库用户名
    final static String user = "dba";
    // 数据库密码
    final static String passwd = "dba";
    // 连接池初始化大小
    final static int initialSize = 5;
    // 连接池最小空闲
    final static int minPoolSize = 10;
    // 连接池最大连接数量
    final static int maxPoolSize = 50;
    // 最小逐出时间,100秒
    final static int maxIdleTime = 100000;
    // 连接失败重试次数
    final static int retryAttempts = 10;
    // 当连接池连接耗尽时获取连接数
    final static int acquireIncrement = 5;
    // Druid数据源
    final static DruidDataSource druidDataSource = getDruidDataSource();
    // 查询次数
    final static int count = 10;

    /**
     * 测试方式: 每种数据源配置信息尽量相同,以求结果更加准确
     * 每种数据源做10次、100次、500次、1000次、2000次、4000次、8000次查询操作 每种查询重复100次,查看100次执行时间的波动图
     * @param args
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, SQLException {

        TestDAO testDAO = new TestDAO();
        System.out.println("查询次数为:" + count);
        System.out.println();
        System.out.println("==========================Druid 测试开始==========================");
        // 测试Druid
        for (int i = 0; i < 100; i++) {
            queryDruid(testDAO, druidDataSource, count);
        }
        System.out.println("==========================Druid 测试结束==========================");
    }

    /**
     * Druid测试
     * @param testDAO
     * @param ds
     * @param count
     * @throws SQLException
     */
    public static void queryDruid(TestDAO testDAO, DruidDataSource ds, int count) throws SQLException {
        // 查询100次以初始化连接池
        for (int i = 0; i < 100; i++) {
            testDAO.query(ds.getConnection());
        }
        // 开始时间
        long startMillis = System.currentTimeMillis();
        // 循环查询
        for (int i = 0; i < count; i++) {
            testDAO.query(ds.getConnection());
        }
        // 结束时间
        long endMillis = System.currentTimeMillis();
        // 输出结束时间
        System.out.println(endMillis - startMillis);
    }

    /**
     * 获取Druid数据源
     * @return
     */
    public static DruidDataSource getDruidDataSource() {
        DruidDataSource dds = new DruidDataSource();
        dds.setUsername(user);
        dds.setUrl(jdbcUrl);
        dds.setPassword(passwd);
        dds.setDriverClassName(driver);
        dds.setInitialSize(initialSize);
        dds.setMaxActive(maxPoolSize);
        dds.setMaxWait(maxIdleTime);
        dds.setTestWhileIdle(false);
        dds.setTestOnReturn(false);
        dds.setTestOnBorrow(false);
        return dds;
    }

}

 

 

        (4)Tomcat Jdbc Pool测试代码:

import java.io.IOException;
import java.sql.SQLException;
import org.apache.tomcat.jdbc.pool.DataSource;

public class TomcatTest {

    // 数据库驱动名称
    final static String driver = "com.mysql.jdbc.Driver";
    // 数据库连接地址
    final static String jdbcUrl = "jdbc:mysql://192.168.0.1:3306/test";
    // 数据库用户名
    final static String user = "dba";
    // 数据库密码
    final static String passwd = "dba";
    // 连接池初始化大小
    final static int initialSize = 5;
    // 连接池最小空闲
    final static int minPoolSize = 10;
    // 连接池最大连接数量
    final static int maxPoolSize = 50;
    // 最小逐出时间,100秒
    final static int maxIdleTime = 100000;
    // 连接失败重试次数
    final static int retryAttempts = 10;
    // 当连接池连接耗尽时获取连接数
    final static int acquireIncrement = 5;
    // Tomcat Jdbc Pool数据源
    final static DataSource tomcatDataSource = getTomcatDataSource();
    // 查询次数
    final static int count = 100;

    /**
     * 测试方式: 每种数据源配置信息尽量相同,以求结果更加准确
     * 每种数据源做10次、100次、500次、1000次、2000次、4000次、8000次查询操作 每种查询重复100次,查看100次执行时间的波动图
     * @param args
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, SQLException {

        TestDAO testDAO = new TestDAO();
        System.out.println("查询次数为:" + count);
        System.out.println();
        System.out.println("==========================Tomcat Jdbc Pool 测试开始==========================");
        // 测试Tomcat Jdbc Pool
        for (int i = 0; i < 100; i++) {
            queryTomcatJDBC(testDAO, tomcatDataSource, count);
        }
        System.out.println("==========================Tomcat Jdbc Pool 测试结束==========================");
    }

    /**
     * Tomcat Jdbc Pool测试
     * @param testDAO
     * @param ds
     * @param count
     * @throws SQLException
     */
    public static void queryTomcatJDBC(TestDAO testDAO, DataSource ds, int count) throws SQLException {
        // 查询100次以初始化连接池
        for (int i = 0; i < 100; i++) {
            testDAO.query(ds.getConnection());
        }
        // 开始时间
        long startMillis = System.currentTimeMillis();
        // 循环查询
        for (int i = 0; i < count; i++) {
            testDAO.query(ds.getConnection());
        }
        // 结束时间
        long endMillis = System.currentTimeMillis();
        // 输出结束时间
        System.out.println(endMillis - startMillis);
    }

    /**
     * 获取Apache tomcat jdbc pool数据源
     * @return
     */
    public static DataSource getTomcatDataSource() {
        DataSource ds = new DataSource();
        ds.setUrl(jdbcUrl);
        ds.setUsername(user);
        ds.setPassword(passwd);
        ds.setDriverClassName(driver);
        ds.setInitialSize(initialSize);
        ds.setMaxIdle(minPoolSize);
        ds.setMaxActive(maxPoolSize);
        ds.setTestWhileIdle(false);
        ds.setTestOnBorrow(false);
        ds.setTestOnConnect(false);
        ds.setTestOnReturn(false);
        return ds;
    }
}

               

 

 

        3.将测试结果粘贴到excel中,生成图表进行对比,可以很直观的看出几种数据源的性能差异,本文底部有此次测试的结果文档。

 

 

        以下就是此次测试结果(本结果只供参考,更具体更准确的测试可以自行进行):

 

        1.测试次数为10次时:



        平均用时(单位:毫秒):

c3p0 32.26
Proxool 33.42
Druid 30.43
Tomcat Jdbc Pool 37.61

 

 

        2.测试次数为100次时:



        平均用时(单位:毫秒):

c3p0 409.94
Proxool 447.49
Druid 382.7
Tomcat Jdbc Pool 386.3

 

 

        3.测试次数为500次时:


        平均用时(单位:毫秒):

c3p0 1700.95
Proxool 2053.85
Druid 1777.36
Tomcat Jdbc Pool 1749.02

 

 

        4.测试次数为1000次时:



        平均用时(单位:毫秒):

c3p0  3549.29
Proxool  3435.8
Druid  3167.59
Tomcat Jdbc Pool  3162.25

 

        因为测试耗时很长,所以我只做到了1000次查询测试,感兴趣的朋友可以继续更大规模的测试或修改相应参数来符合项目自身情况,这里不比去追究测试数据的准确性,比较测试程度还不够,且存在很大的偶然性,大家可以修改以上代码进行更精准的测试,只需要将数据导入到本文末尾的excel表格中即可生成相应测试图表。

        很多人总是会回复在问“你的测试准不准啊?”,“你的测试一点都不准!”等等,其实我想说的是:不要太在意别人的结果,重要的是自己去做!

 

  • 大小: 98.5 KB
  • 大小: 104.2 KB
  • 大小: 79.7 KB
  • 大小: 75.3 KB
9
4
分享到:
评论
7 楼 ssy341 2013-10-11  
支持一个,方法很全面,可以参考,感觉现在用druid的还是比较少,文档不是很全面
6 楼 iskp 2013-08-06  
g21121 写道
iskp 写道
楼主,明显改过这篇文章,昨天的测试结果让我很意外,今天的结果还算是正常。


这种测试其实存在很大偶然性,比较片面


主要是测试的差距有点偏大,也许是测试用例的设计不一样
5 楼 g21121 2013-08-06  
iskp 写道
楼主,明显改过这篇文章,昨天的测试结果让我很意外,今天的结果还算是正常。


这种测试其实存在很大偶然性,比较片面
4 楼 iskp 2013-08-06  
楼主,明显改过这篇文章,昨天的测试结果让我很意外,今天的结果还算是正常。

3 楼 Tyrion 2013-08-05  
g21121 写道
Tyrion 写道
Druid是阿里系的吧,据说性能方面超过了其它同类产品,博主是生产环境中用过?

是阿里巴巴的,生产中没有用到过,我也是听“据说性能非常好”才做测试的,图片里面绿色的就是Druid,某些方面性能还是可以的,但开源项目文档方面非常差


前段时间看了Druid作者放在github上的介绍,对于使用者最主要的担心是Druid目前太小众,出了问题只能找阿里的人回答或自己研究源码,对于有项目进度压力的情况下这个肯定不是首选。
2 楼 g21121 2013-08-05  
Tyrion 写道
Druid是阿里系的吧,据说性能方面超过了其它同类产品,博主是生产环境中用过?

是阿里巴巴的,生产中没有用到过,我也是听“据说性能非常好”才做测试的,图片里面绿色的就是Druid,某些方面性能还是可以的,但开源项目文档方面非常差
1 楼 Tyrion 2013-08-05  
Druid是阿里系的吧,据说性能方面超过了其它同类产品,博主是生产环境中用过?

相关推荐

Global site tag (gtag.js) - Google Analytics