mysql数据库的一个测试结果,有些出乎意料

03-08-06 KillerMan
库是空库,比较直接得到1000次数据库连接和从池中得到连接的性能差别

下边是代码;

PoolManager pm = PoolManager.newInstance();

long total = 0;

int i = 0;

for (; i < 1000; i++) {

long curTime = System.currentTimeMillis();

Connection conn = pm.getConnection("mysqlPool");

long afTime =System.currentTimeMillis();

long margin = afTime-curTime;

total+=margin;

System.out.println(

"得到第"

+ i

+ "个数据库连接:"

+ conn

+ " 耗时:"

+ margin);

pm.freeConnection("mysqlPool", conn);

}

System.out.println("平均耗时为:"+(total/i));

pm.release();

结果:

* 数据库测试,测试连接池在并发访问1000客户端连接时的工作效率

* 1,不加入释放语句

* 1000次连接,耗时最短40毫秒,最长150 毫秒,平均在46左右

* 2,加入释放语句

* 10000 次 得到连接,最短30毫秒,最常40毫秒,平均在35左右

         

KillerMan
2003-08-06 16:38
对连接池化后,除了性能比较稳定(摆动幅度较小)外,在得到连接的时间上差别也不算很大。

再,N多的地方都说mysql在并发100以上的访问,性能会大幅下降,从这个测试也看不出来。

探讨一下。

robbin
2003-08-06 17:20
还是一句老话,你这样的测试是无意义的。性能测试是一门学问,需要投入很多的人力物力财力资源去测试,测试用例,测试环境,测试工具都要精心设计。单看你的测试用例就不对,结论也更加无意义。而且这样无意义的测试会误导初学者。

raynix
2003-08-06 17:41
你这只是重复连接/释放N次,并没有并发的代码阿。如果把你的代码做成一个thread,然后run N个这种thread,似乎与你的测试并发的目的更接近些。

robbin
2003-08-06 18:41
噢,对了,再告诉你一个经典的产生误导的测试:就拿你上面的例子,或者再加点料,可以这样来做:

写一个最简单的Servlet/JSP(用Servlet/JSP的目的是便于测试多线程并发访问,其实不用Servlet/JSP也可以测出同样的结果)。这个Servlet/JSP是这样的,从数据库连接池获得一个连接,然后做一个最简单的select查询,比如select count什么的,然后关闭连接,把连接返回到连接池中。另外建议把你的System.out语句去掉,消除对测试结果的影响。

然后使用Apache Web Server带的ab测试工具来并发访问该Servlet/JSP:

ab -n 1000 -c 20 http://.../TestServlet

上述命令行的意思是模拟20个用户并发访问该Servlet,共发送1000个请求,ab测试会返回很多统计信息,包括多长时间完成测试,平均每请求需要多少秒完成,以及成功完成的请求数,失败的请求数等等,这是一个非常专业非常有用的的web性能测试工具。

按照正常的逻辑,大家一定会认为,由于并发20个请求,数据库连接池当然会分配20个数据库连接给Servlet来使用的,并且测试的Servlet逻辑如此简单,运行速度非常快,自然会花很少的时间就可以完成测试过程。

但是测试结果一定大出意料之外!实际上测试需要花很长很长很长的时间才能完成,甚至无法正常完成测试过程!测试完成以后参考ab的测试报告,就可以看到,平均每个Servlet要花很长时间才能完成请求,并且至少有超过60%以上的请求都失败了。大部分Servlet都甚至没能正常运行,这是为什么?如果你的app server有数据库连接池监视工具,你还可以看到更奇怪的现象,就是自始至终,数据库连接池中只使用了一个数据库连接,其它所有的连接,即使你预创建了,也一直被闲置,并没用被连接池分配给Servlet,这又为什么?为什么连接池放着闲置的连接不用? 就算并发Servlet再多,也硬是只用一个连接,这样的话,连接池的作用等于完全没用了?

做完上面的测试以后,你在你的Servlet里面简单加上一句话,Thread.sleep(1000);然后再重复上面的测试。就会发现测试完成时间大大缩短,平均每Servlet完成请求的时间非常短,而平均每秒处理的请求数有巨大的提升,同时几乎所有的Servlet都成功的完成请求,几乎没有失败的请求。并且这个时候,你可以观察到数据库连接池的的确确是分配了20个连接给Servlet来使用的。这又是为什么?

这就是一个经典的测试陷阱:让程序跑的更慢一些,反而得到了性能的巨大提升和程序稳定性的巨大提升!这是否意味着数据库驱动的程序我们应该多加点Thread.sleep语句呢,让程序跑得慢点,反而可以极大的提升性能呢?

这个例子说明了性能测试,绝对不是一般人可以干得来的活。测试是一门高深的学问,测试需要巨大的投资,测试需要精心的设计。像IBM,HP这样的大公司有自己专门的测试实验室,每年投入巨资进行软件硬件的测试,测试结果最终就是一个简单的proposal罢了,可是这个简单的proposal凝结了无数的智慧和资源。

而我们自己随随便便写一个测试用例,然后在自己的机器上随便跑跑,就冒冒失失的宣布某某软件的性能如何如何,简直是井底之蛙!浅薄之至!我每次看到这样的所谓某某软件评测报告,我就无言语了,愤怒的无言语了。自己夜郎自大,关起门来意淫一下也没有人管得着,但是到处把这种荒谬的测试结论到处宣传,简直就是FUD,会严重误导初学者!像TSS的j2ee vs .net petstore 测试就是如此。我还时不时在网络上看到什么asp,jsp,php性能测试,TMD胡说八道,跟白痴一样。

所以性能测试千万要慎重,不要随随便便下什么结论,这样只能带来极大的危害。

猜你喜欢
8Go 1 2 3 4 ... 8 下一页