阅读更多
前些日子做了一些系统调优的工作,感觉倒是有必要记录下来。
需要调优的系统是一套中间层的Web service API,其中有一个API需要获取大量的数据,所以在进行load测试的时候,数据库的数据达到千万级后,就出现了相应时间过长,甚至出现exception的情况。想了解如何进行性能的优化,就要先看一下QA是如何测试的。QA的load测试分为两个部分
1. endurance测试,这种测试QA会先制定一个参数叫hit/s,也就是说当测试开始后,load测试工具(loadrunner)会逐渐增加并发的数量,从而使目标达成。举例说,如果开始时并发为1,那么为了达到目标,每个处理必须在200ms之内,这样才能达到5hit/s的要求。如果处理的速度不够,系统会自动增加并发数,假设并发为10,那么每个处理的时间只需要2s,这样就能达到目标。当然这种测试不会因为无法达到目标而无限制的增加线程,一般来讲,如果你的程序不好,并发越大,死的越快。
评定这个测试的另外一个指标是每个处理的最大时间,比如500ms/hit,也就是说每个处理不能超过500ms。
整个测试的结果一般是看95%的处理结果是否符合要求。
2. stress测试,这种测试是一种极端测试。比如参数为300个并发跑一小时。这种测试允许exception的发生,但是比例不能超过90%。
说完了测试的方法,再来说说集中测试中的常见问题:
1. 内存泄露:这个比较常见,可以上网找找,描述的很清楚了,不想再这里在多说。这种问题在endurance的测试中会暴露出来,解决办法就是看thread dump,找到问题所在
2. 数据库连接池泄露:这个问题应该分成两个部分来看。第一种是错误的失误处理造成连接没有被回收。我们现在常用SPring和hibernate, 说实话,上手时很容易,但是想写好可没那么简单,在加上分布式开发和不严谨的code review,就会造成不知不觉中的链接泄露。这种问题在stress中会非常容易暴露,有时在endurance中反而不容易察觉。
另外一种是由于Sql时间过长,造成连接池来不及回收造成的。这种问题不一定是代码错误,而是由于代码的质量低造成的,以下几个典型的bad sql:
a. 大量的重复opern and close connection
b. 不必要的join
c. 错误的统计函数
以上的问题如果出现在大数据量或者高并发的情况下,就会造成连接资源不断下降,最后导致崩溃。
接着说说几个开发人员常用的工具:
1. Jmeter: QA有几十万的loadrunner可以做load的测试,我们怎么办?Jmeter,apache的软件,应该说相当不错,极易上手而且数据和图形界面非常清晰。dev可以用来惊醒load环境的moni,并且得到统计数据
2. JProfile:这个就不是免费的了。Jprofile的功能非常强大,部署到app server后,可以获取象数据库连接、内存、CPU等系相关数据,生成snapshot,从而进行各种分析。
基本能想到的就这些了,具体的分析过程就不献丑了。见仁见智。