DBCP,C3P0,Tomcat_JDBC druidDatasource 性能及稳定性测试

本文对比测试了DBCP、C3P0、Tomcat_JDBC和DruidDataSource四种数据库连接池在不同线程数下的性能表现,同时评估了它们的稳定性。

DBCP,C3P0,Tomcat_JDBC druidDatasource性能及稳定性测试

 

1.测试环境:

硬件环境:

数据库服务器:2U*8核 8G内存 
测试服务器:   2U*8核 6G内存

软件环境:

jdk:   

1.6.29

mysql:

5.0.77

mysql_driver:

mysql-connector-java-5.0.8-bin.jar

 

DBCP:

commons-dbcp-1.4.jar

下载地址: http://commons.apache.org/dbcp/

commons-pool-1.5.6.jar

下载地址: http://commons.apache.org/pool/

C3P0:

c3p0-0.9.1.2.jar

下载地址: http://www.mchange.com/projects/c3p0/index.html

log4j-1.2.8.jar(c3p0需要添加此包)

下载地址: http://logging.apache.org/log4j/

 Tomcat_JDBC:

        tomcat-jdbc.jar

下载地址: https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

或者在tomcat安装根目录下的lib目录中直接拿来用之

tomcat-juli.jar

下载地址:(没找到)

在tomcat安装根目录下的bin目录中直接拿来用之

 

配置信息:

数据库连接超时时间设置为:   10年

数据库支持最大连接数设置为:2000

 

初始化连接池大小:10

连接至最小活动线程数:10

连接池最大活动线程数:100

 

其他配置均保持各个连接池的默认配置

 

2.性能测试:  

测试点:

在多线程多任务的条件下,各个连接池获取连接然后马上关闭连接,比较所消耗的时间。

 

在网上看了好多关于数据库连接池方面的测试,

大多数测试过程中,包括了执行sql语句部分,即,创建连接,执行sql语句,关闭连接,

一开始我也是这样测试,

测试过过程中,发现数据很不稳定,这几个连接池都是忽快忽慢,

经过思考、分析,个人 觉得这样是不准确的,执行sql语句时,测试已经不是数据库连接池的性能了,

完全是数据库驱动程序(例如mysql_driver )和数据库本身的性能,

 

数据库连接池负责的仅仅是建立DataSource,获取(从连接池中获取)Connection,关闭(放回到连接池)Connection,

 

因此,

我在测试时,没有计算初始化连接池(建立DataSource)的时间,而是连接池“获取连接然后马上关闭连接”的时间。

 

测试结果:

 

 

DB POOL线程
数量
单线程
执行次数
消耗时间
(ms)
开始时间
(ms)
结束时间
(ms)
平均消耗
时间(ms)
平均单条
时间(ms)
DBCP 10 10002511328863445815.001328863446066.00 2510.0251
2521328863466569.001328863466821.00
2511328863477174.001328863477425.00
2541328863487555.001328863487809.00
2471328863499474.001328863499721.00
C3P0 10 10007811328863372064.001328863372845.00 802.80.08028
7891328863385489.001328863386278.00
8791328863401335.001328863402214.00
7731328863413608.001328863414381.00
7921328863424693.001328863425485.00
TomcatJDBC 10 10001911328863272642.001328863272833.00 191.80.01918
1971328863303126.001328863303323.00
1871328863313262.001328863313449.00
1951328863324253.001328863324448.00
1891328863334700.001328863334889.00

 

 

 

DB POOL线程
数量
单线程
执行次数
消耗时间
(ms)
开始时间
(ms)
结束时间
(ms)
平均消耗
时间(ms)
平均单条
时间(ms)
DBCP 100 10007861328862922748.001328862923534.00 810.40.008104
8531328862939832.001328862940685.00
8101328862955354.001328862956164.00
8071328862981344.001328862982151.00
7961328862994825.001328862995621.00
C3P0 100 100025171328863021884.001328863024401.00 2248.80.022488
23401328863040949.001328863043289.00
19681328863075044.001328863077012.00
22561328863092216.001328863094472.00
21631328863114138.001328863116301.00
TomcatJDBC 100 10007521328863155803.001328863156555.00 7260.00726
7251328863171617.001328863172342.00
6941328863183983.001328863184677.00
7031328863195628.001328863196331.00
7561328863209798.001328863210554.00

 

 

DB POOL线程
数量
单线程
执行次数
消耗时间
(ms)
开始时间
(ms)
结束时间
(ms)
平均消耗
时间(ms)
平均单条
时间(ms)
DBCP 150 100019191328861533609.001328861535528.00 1854.40.012363
19571328861551638.001328861553595.00
18691328861746964.001328861748833.00
19161328861791533.001328861793449.00
16111328861832003.001328861833614.00
C3P0 150 100027261328861869415.001328861872141.00 2990.80.019939
25701328861895349.001328861897919.00
33421328861912351.001328861915693.00
32181328861929664.001328861932882.00
30981328861950163.001328861953261.00
TomcatJDBC 150 10008771328861974599.001328861975476.00 8610.00574
8211328861990969.001328861991790.00
8901328862016507.001328862017397.00
8571328862037077.001328862037934.00
8601328862052490.001328862053350.00

 

 

DB POOL线程
数量
单线程
执行次数
消耗时间
(ms)
开始时间
(ms)
结束时间
(ms)
平均消耗
时间(ms)
平均单条
时间(ms)
DBCP 300 100039081328862516139.001328862520047.003851.80.012839
38501328862408362.001328862412212.00
39391328862440877.001328862444816.00
38061328862469116.001328862472922.00
37561328862495883.001328862499639.00
C3P0 300 10006111 1328862711585.00 1328862717696.006233.20.020777
51621328862618669.001328862623831.00
62611328862638870.001328862645131.00
68321328862659598.001328862666430.00
68001328862681808.001328862688608.00
TomcatJDBC 300 100034581328862152316.001328862155774.003403.80.011346
33761328862308211.001328862311587.00
33971328862227685.001328862231082.00
33421328862261681.001328862265023.00
34461328862358400.001328862361846.00

 

结论:

总体性能:TomcatJDBC > DBCP > C3P0

网上好多资料都说C3P0的性能要好于DBCP,从我的测试结果来看并不是这样,也许是我的配置有不正确的地方,

 

测试时最大的活动线程配置为100,并发为150线程时,TomcatJDBC的优势明显,

也就是当并发超过连接池最大的活动线程数,但并没有超过太多的情况下,TomcatJDBC的优势明显,

 

我测试的结果都是毫秒级,

对于一个小型的系统,并发压力不大时,选择哪个连接池都没有太大差别,考虑更多的应该是连接池的稳定性。

 

3.稳定性测试:

测试点:

1.当数据库由于未知原因关闭,重新启动后,连接池是否可以自动重连,无需重启应用服务。

2.应用服务正常,数据库服务正常,但是网络环境异常,导致连接中断,此时连接池中连接处于“半连接”状态,

 

 

现象:

在不重启应用服务的情况下, mysql数据库进行重启操作,mysql完全重启后,执行程序,

TomcatJDBC和DBCP并没有自动重连,重复执行查询语句,会一直报异常,重启应用服务后恢复正常

C3P0进行了自动重连,重复执行查询语句,执行正常。

 

结论:

默认配置条件下,TomcatJDBC和DBCP并没有自动重连机制,查看官方文档,这缺陷可以通过修改配置解决。

 

 

另:

连接池重连机制,有2种:

 

1.同步验证方式:

每次获取连接或关闭连接时,执行一个预定义的验证语句(sql语句),

验证连接池中的连接是否有效,如果验证失败,彻底关闭此连接,

这种方式会导致每次执行数据库操作时都有额外的开销,对性能影响较大。

 

2.心跳验证方式:

每隔特定的时间进行一次验证,执行一个预定义的验证语句(sql语句),

验证连接池中的连接是否有效,如果验证失败,彻底关闭此连接,

可以根据具体情况,适当的调节验证间隔时间。

这种方式以牺牲较小的性能开销为代价,来保持系统的稳定性。

 

 

 

4.心得

自从tomcat7发布以来,网络上开始出现一个新的连接池的影子,tomcat jdbc,
经过测试,发现tomcat jdbc的性能果然不错,是连接池不二的选择,
本人E文水平有限,没办法把E文翻译的那么优雅,
tomcat jdbc的其他优点,还请看它的官网介绍
https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

这篇文章详细介绍阐述dbcp与c3p0的一些不足:
Why another connection pool project

 

 

 

 

重连机制:

不推荐使用同步验证方式,

如果系统架构中,网络环境(应用服务与数据库服务之间)不稳定,硬件环境不稳定,推荐使用心跳验证方式。

如果系统架构中,网络环境和硬件环境都机器稳定,而且对数据库I/O性能要求较高时,可以不进行验证。

转自:http://aub.iteye.com/blog/1404219



补充,刚看到的druidDatasource 测试


Changes (30)

View Page History
h1. 测试运行注意事项 
添加 -server参数 

h1. 场景一 
单线程测试,连续执行100万次,对比时间、YungGC、FullGC的情况。这个场景用于测试非激烈竞争的情况下的性能差别。 

h3. 测试代码 
svn : http://code.alibabatech.com/svn/druid/trunk/src/test/java/com/alibaba/druid/pool/benckmark/Case0.java

h3. 测试结果 
连续执行1000,000次,Druid和DBCP的测试对比结果: 
||连接池|| 时间(毫秒) || YungGC || FullGC || 
| Druid |  277  221 | 16  6 | 0 |
| DBCP |  1,647  1,606 | 70 |0|
| BoneCP | 762 | 4 |0|

h3.  测试代码  结论
{code} Druid和DBCP执行时间相差大约6倍,YungGC相差4倍多,FullGC都没有。由此看来,DruidDataSource在执行时间远胜于DBCP,而且产生的小对象比DBCP小得多。
public class Case0 extends TestCase { 

private String jdbcUrl; 
private String user; 
private String password; 
private String driverClass; 
private int initialSize = 10; 
private int minPoolSize = 1; 
private int maxPoolSize = 2; 
private int maxActive = 2; 

protected void setUp() throws Exception { 
jdbcUrl = "jdbc:fake:dragoon_v25masterdb"; 
user = "dragoon25"; 
password = "dragoon25"; 
driverClass = "com.alibaba.druid.mock.MockDriver"; 

h1. 场景二 
多个线程,连续打开关闭连接1000,000次。 

public void test_0() throws Exception { 
DruidDataSource dataSource = new DruidDataSource(); 
h3. 测试代码 
http://code.alibabatech.com/svn/druid/trunk/src/test/java/com/alibaba/druid/pool/benckmark/Case1.java

h3. 测试结果 
连续执行1000,000次,Druid和DBCP的测试对比结果: 
||连接池||线程数量 ||时间(毫秒) || YungGC || FullGC || 
| Druid |2 |1,177 |  34  | 0 dataSource.setInitialSize(initialSize);  | 
| DBCP |2 |2,738 | 139 |0|
| BoneCP |2 |2,242 | 8 |0| 
| Druid |5 |3,7027 |  80  | 0 dataSource.setMaxActive(maxActive);  | 
| DBCP |5 |39,203 | 350 |0|
| Druid |10 |11,172 |  162  | 0 dataSource.setMinIdle(minPoolSize);  | 
| DBCP |10 |79,220 | 702 |0|
| Druid |20 |38,817 |  328  | 0 dataSource.setMaxIdle(maxPoolSize);  | 
dataSource.setPoolPreparedStatements(true); 
dataSource.setDriverClassName(driverClass); 
dataSource.setUrl(jdbcUrl); 
dataSource.setPoolPreparedStatements(true); 
dataSource.setUsername(user); 
dataSource.setPassword(password); 
dataSource.setValidationQuery("SELECT 1"); 
dataSource.setTestOnBorrow(true); 
| DBCP |20 |159,966 | 1402 |0|

for (int i = 0; i < 10; ++i) { 
p0(dataSource, "druid"); 

System.out.println(); 

h3. 结论 
2个线程时,这时候时候激烈的并发获取连接,Druid和DBCP的执行时间差距缩小了,不到3倍。
public void test_1() throws Exception { 
final BasicDataSource dataSource = new BasicDataSource(); 
5个线程时,获取连接的线程超过了maxActive(数量为2),DBCP性能急剧下降,Druid和DBCP的执行时间差距达到了13倍。
dataSource.setInitialSize(initialSize); 
dataSource.setMaxActive(maxActive); 
dataSource.setMinIdle(minPoolSize); 
dataSource.setMaxIdle(maxPoolSize); 
dataSource.setPoolPreparedStatements(true); 
dataSource.setDriverClassName(driverClass); 
dataSource.setUrl(jdbcUrl); 
dataSource.setPoolPreparedStatements(true); 
dataSource.setUsername(user); 
dataSource.setPassword(password); 
dataSource.setValidationQuery("SELECT 1"); 
dataSource.setTestOnBorrow(true); 
10个线程时,Druid和DBCP的执行时间差距拉近为7倍。
for (int i = 0; i < 10; ++i) { 
p0(dataSource, "dbcp"); 

System.out.println(); 


private void p0(DataSource dataSource, String name) throws SQLException { 
long startMillis = System.currentTimeMillis(); 
long startYGC = TestUtil.getYoungGC(); 
long startFullGC = TestUtil.getFullGC(); 

final int COUNT = 1000 * 1000; 
for (int i = 0; i < COUNT; ++i) { 
Connection conn = dataSource.getConnection(); 
conn.close(); 

long millis = System.currentTimeMillis() - startMillis; 
long ygc = TestUtil.getYoungGC() - startYGC; 
long fullGC = TestUtil.getFullGC() - startFullGC; 

System.out.println(name + " millis : " + NumberFormat.getInstance().format(millis) + ", YGC " + ygc + " FGC " + fullGC);


{code}
内容概要:本文围绕“空地多无人平台协同路径规划技术”的论文复现展开,重点介绍了基于Matlab的多无人机与地面无人平台协同路径规划的算法实现与仿真研究。研究系统性地整合了无人机三维路径规划、动态避障、多机协同、任务分配及防撞机制等核心技术,结合智能优化算法(如遗传算法、粒子群算法、灰狼优化算法等)与经典路径规划模型(如Dubins路径、A*、RRT等),在复杂威胁环境下实现了高效、安全的协同路径规划。文中提供了完整的Matlab代码支持,便于科研人员进行算法验证、性能对比与二次开发,并强调通过复现高水平学术论文(如EI、SCI期刊及硕博论文)深入掌握该领域的前沿方法与技术路线。; 适合人群:具备一定Matlab编程基础,从事无人机系统、自动化控制、人工智能、路径规划等相关领域研究的研究生、科研人员及工程技术人员,尤其适用于正在开展科研项目、撰写学位论文或希望提升算法实践能力的研究者。; 使用场景及目标:① 复现并深入理解空地协同路径规划领域的高水平论文算法;② 掌握Matlab在多智能体路径规划中的建模、仿真与可视化方法;③ 应用于科研课题、毕业设计、项目申报及算法创新实践中,提升研究的技术深度与工程可行性。; 阅读建议:建议结合文中提供的网盘资源(含完整代码、仿真模型及参考文献资料)同步学习,优先选择与自身研究方向契合的案例进行复现,注重算法原理与代码实现之间的映射关系,并在掌握基础方案后尝试进行参数调优、算法融合或引入新约束条件以实现改进与创新。
内容概要:本文基于Android 15_r17源码深度解析Binder机制的核心原理与实现流程,涵盖Binder驱动交互、服务注册与获取、跨进程通信流程及关键类的作用。文章详细剖析了首个Binder服务ServiceManager的启动与发布过程,阐明其作为上下文管理者通过ioctl设置为Context Manager的机制;系统梳理了ServiceManager.addService和getService的全流程,包括Java层通过BinderProxy到native层BpBinder与IPCThreadState的跨进程调用链;解析了oneway与非oneway调用在事务处理与回复机制上的差异;完整展示了app调用bindService时Binder引用的流转过程,涉及Parcel中flat_binder_object的序列化与反序列化;同时归纳了Binder的特性如句柄管理、死亡通知及异常处理机制。文中还明确指出handle由Binder驱动在创建binder_ref时生成,客户端仅作引用。; 适合人群:具备Android系统开发经验,熟悉C++/JNI及操作系统原理,有一定Framework层开发背景的中高级研发人员; 使用场景及目标:①深入理解Android Binder驱动层与应用层的交互机制;②掌握ServiceManager的初始化与服务注册原理;③分析Binder跨进程调用中数据序列化、句柄管理与线程处理流程;④研究oneway调用与普通调用的差异及异常处理机制; 阅读建议:本文聚焦源码级分析,建议结合Android 15_r17源码同步阅读,重点关注IPCThreadState、ProcessState、BpBinder/BnBinder及Parcel的实现细节,理解Binder在内核与用户空间的数据流转过程。
内容概要:本文系统阐述了SDD(规范驱动开发)与Harness(驾驭式流程管理)相结合的AI全栈开发新范式,旨在解决AI编程助手在复杂工程中因上下文丢失、规范不一致导致的“代码能跑、工程难成”问题。SDD将规范作为唯一真实源,通过定义精确的领域语言(如OpenAPI、Gherkin)约束AI生成行为,确保前后端与测试间的一致性;Harness则提供执行引擎,通过上下文隔离、行为禁令、任务原子化与流程锁步等方式,引导AI在已有高质量参照下进行模式复刻,提升生成代码的可用性与PR保留率。二者共同构建从需求到生产的工程化闭环,实现规范可验证、变更可追溯、运维可反馈的“确定性”交付。; 适合人群:具备全栈开发经验、正在探索AI辅助工程落地的研发工程师、技术负责人及AI工程化实践者;尤其适合面临多模块协同、架构一致性维护难题的中高级开发者。; 使用场景及目标:①在AI辅助下高效生成符合统一架构规范的前后端代码与测试用例;②建立可编译、可测试、可持续演进的全栈自动化开发流水线;③实现从需求变更到生产部署的闭环验证与自动回滚机制;④提升AI生成代码在实际项目中的采纳率与系统稳定性。; 阅读建议:此资源强调工程思维转变,建议结合实际项目尝试将架构决策转化为机器可读规范,并搭建Harness流程控制机制,在实践中体会“约束生成”优于“自由创造”的AI协作新模式。
内容概要:本文档聚焦于“独立售电商购售电策略研究”,通过Python编程实现电力市场中独立售电商的购售电优化决策模型。研究内容涵盖在市场化竞争环境下,售电商如何制定最优购电计划、设计售电定价机制,并有效应对电价波动、负荷不确定性及新能源出力随机性等挑战,以实现利润最大化与风险控制的双重目标。文档深入探讨了多时间尺度调度、不确定性建模、市场竞价机制等核心技术,并利用代码进行仿真验证。此外,文档还提供了大量相关科研主题的参考资料,涉及微电网调度、综合能源系统、虚拟电厂、电动汽车、鲁棒优化等多个前沿方向,展现了广阔的技术应用前景和深厚的学术价值。; 适合人群:具备一定电力系统基础知识和Python编程能力,从事电力市场、能源管理、优化调度等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 学习并复现独立售电商在电力市场中的购售电决策模型;② 掌握基于Python的电力市场仿真与优化方法;③ 借鉴相关代码实现思路,拓展至微电网、虚拟电厂、需求响应等领域的研究与应用; 阅读建议:此资源以实际代码实现为核心,建议读者结合文中提及的相关研究主题进行系统性学习,重点关注模型构建逻辑与算法实现细节,同时可通过提供的网盘链接获取完整代码资源以便调试与二次开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值