随笔-23  评论-6  文章-1  trackbacks-0

         影响性能的测试报告(数据库版)

引言

如需转载,请与笔者联系

 

前提:项目组里无用到SPRING进行事务的管理。项目里以功能划分到每个人手里,

形成了BODAOACTIONVIEW都是单人负责。在DAO中每个动作都以

      封闭式的形式存在。

问题:造成事务的不连贯性。功能是做出来了,性能问题迟早暴露。

测试:主要针对程序频繁请求数据库连接对WEB应用所造成影响做一个测试。

 

 

先做必要的说明,一步步引入正题,先从性能瓶颈开始:

性能瓶颈

所有的应用程序都存在性能瓶颈,为了提高应用程序的性能,就要尽可能的减少程序的瓶颈。以下是在JAVA程序中经常存在的性能瓶颈。

pingjing.jpg
了解了这些瓶颈后,就可以有针对性的减少这些瓶颈,从而提高JAVA应用程序的性能

 

数据库连接池工作原理

关于连接池的实现原理测试方案:

经过资料的收集与APACHE DBCP里连接池的查阅,对现有的连接池工作

原理有两种方式:

1.        数据库预先设置配置好的连接数。待得到用户请求连接,传出一个连接,而后为了保持供应数再提前创建连接,即提前预备连接数供请求。比如:

5个通行道代表最大激活的连接数,最小2个闲置连接数。也就是说连接池里始终预备了2个可随时提供的连接,连接的创建开销是比较大的,连接池的存在就是了能够最小化的解决创建所等待的时间。

  1            O

  2            O

  3            *

  4            *

  5            *

  如上图,当1分配出去时由于池中连接数剩一个,为保持最小闲置,会自动创建一个新的连接以防止再次请求等待创建的时间。这样确实减少了等待的时间,但是数据库创建的开销方面并未得到解决。如果把1-5比喻成汽车,那么这种情况下每量车都是一次性使用。1被请求后下一个连接将是6来接替。那么如何能够重复利用1减少数据库开销。于是引出第二种方式。

 

2.        回收使用完后的连接,放回到池中进行循环利用。这么做必须能保证2

   .  使连接能够保持有效的回收。

   .  约束使用者使用释放的动作,而不是直接把连接close.

 

本人使用的是APACHE DBCPBasicDataSource的连接池基本实现,

经过代码与测试结果显示,其工作方式是基于二的。

 

BasicDataSource测试用例

请看测试用例

测试结果:


2组数据:

并发应用数:100 模拟连接数:6

运行平均耗时:2956

共使用51个连接

运行平均耗时:3391

2共使用52个连接

运行平均耗时:2616

共使用47个连接

运行平均耗时:3377

共使用41个连接

运行平均耗时:3673

共使用46个连接

2组数据共执行5;平均耗时为:3229毫秒

平均使用47个连接

 

3组数据:

并发应用数:85 模拟连接数:9

运行平均耗时:4830

共使用53个连接

运行平均耗时:3247

共使用49个连接

运行平均耗时:4116

共使用40个连接

运行平均耗时:4070

共使用43个连接

运行平均耗时:4053

共使用54个连接

3组数据共执行5;平均耗时为:4063毫秒

平均使用47个连接

 

4组数据:

并发应用数:140 模拟连接数:3

运行平均耗时:2076

共使用47个连接

运行平均耗时:3104

共使用51个连接

运行平均耗时:2048

共使用43个连接

运行平均耗时:2421

共使用50个连接

运行平均耗时:2751

共使用50个连接

4组数据共执行5;平均耗时为:2480毫秒

平均使用48个连接

 

每次测试的结果都可能不同,但是所得到的结论是一致的。数据显示不合理的请求使用连接严重的影响应用所能承受的并发数量,响应的时间也因此受到影响。

 

目前普遍存在的问题

没有把事务控制好,一般会出现以下的情况:

事务(){

  流程1();

  流程2();

}

可以看出流程12里都是单独创建连接,并在自己的流程里完成操作。

如果在流程2里出现异常,那么流程1所做的操作是不可恢复的。

如果能控制在事务范围内,如:

事务(){

  Connection con;

  流程1(con);

  流程2(con);

  con.close();

}

那么数据库少提供一个连接,事务的完成性也得到体现。在并发数量大的时候,

效率上就有非常明显的区别。

解决方案

1.  尽量保持少的请求

DAO中有update()方法,则应再扩展一个方法update(Connection conn)

在业务逻辑事务里调用update(Connection conn),一般情况下调用update()

2.  对于数据不变的情况采用缓存技术,或部分缓存技术。

      可参照一些相关的开源的项目(JIVE)。

posted on 2005-09-25 17:21 ceaboat 阅读(1658) 评论(4)  编辑  收藏 所属分类: JAVA小结

评论:
# re: 影响性能的测试报告(数据库版) 2005-09-25 19:40 | martin xus

讨论一下:)

一:
事务(){
流程1();
流程2();
}

这样的事务完全可以控制的,例如:采用command的模式

Transactable tx = null;
try{
tx.begin();
command = cmd.execute();
tx.commit();
} catch (Throwable e) {
if (tx != null) {
try {
tx.rollback();
} catch (Exception he) {
throw new GeneralFailureException("事务回滚出错", he);
}
}
}

这完全没有问题的.


二:
个人认为connection没有必要扩大到外面来,
Connection con;
流程1(con);
流程2(con);
con.close();
connection应该是透明的,不应该出现在你的业务代码中,再说,你的一个application不是有connection pool吗?应该把connection交给容器去管理.

再者:
如果出现以下任一种情况怎么办或者被别人误用:
(1):你的connection 被声明为static
(2):代码没有执行完毕,抛出异常,而又没有合理处理connection
那么这样你的连接就可能被占着不放.做gc同样也释放不了.你的server肯定会菪机!


你说呢?
  回复  更多评论
  
# re: 影响性能的测试报告(数据库版) 2005-09-25 20:24 | ceaboat
我这里只做最普通的例子说明,并不是重在一定使用这种方式,重点是在于事务进行统一,虽然大家都知道这个,但是出呼意料,在项目中我看到更多的是使用
事务(){
流程1();
流程2();
}
对于我来说难以理解,于是有必要做这个测试报告,在会议上进行讨论。
当然在正常使用中,异常的处理是必须的,但不是这个测试的重点所在。
重点在于不合理的使用连接,频繁的进行网络交互所给系统带来的负担。  回复  更多评论
  
# re: 影响性能的测试报告(数据库版) 2005-09-25 20:32 | InPractice
在同一个事务中,流程1和流程2共用一个连接应该效率较高。实践中大家可能都没有注意这个。因为一般是DAO和SERVICE两层。每个DAO是独立的,组合到Service中时也没有特意让两个DAO共享同一个连接,就会出现上面的情况。  回复  更多评论
  
# re: 影响性能的测试报告(数据库版) 2005-09-26 09:04 | martin xus
在一个项目中,非不得以,事务不应该交给组员去做的,对他们来说,这是不允许的.
在他们的模块中只是简单的业务处理.普通的代码,调用相应的service..

开发前,先给组员开 “项目规范动员大会” :)  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: