闲说性能测试
作者:网络转载 发布时间:[ 2015/6/4 14:12:25 ] 推荐标签:性能测试
瓶颈定位
要定位瓶颈,首先需要知道应用服务器的哪项指标没有达到预期,是CPU利用率还是IO利用率或是都不高,这可以通过以上介绍的三个stat工具观察出来,如果没有看到哪项值比较高,至少也可以得到“都不高”的结论,而都不高的时候,或许意味着你的应用程序不像你想象的那么高效,一定,一定,在某个点上正在激烈的竞争者或者阻塞。程序会平白无故效率低下!
当然除了通过利用率,可以看到CPU或者IO的忙闲程度,有时我们还需要知道具体的数字,比如,哪种IO才算繁忙?
举个例子,这次性能测试时我使用了一个工具:ifstat,它并非系统自带的工具,需要手动安装,安装过程非常简单,自行google即可。
安装完毕后,将ifsta命令加入到path变量中,即可在全局使用ifstat命令,使用后的效果大致是这样:
eth0 代表了操作系统的第一张网卡。从这里可以看到此时这张网卡的读入速率是15M,出口是8M左右,而这张网卡的速率为:
也是1000Mbit/s ,因为8B10B编码的关系,换算后理论的带宽为100M/S,100:15 利用率为15%,这个时候我们才可以说IO的利用率不高。IO不算繁忙。
同样的,有时会出现一种情况:CPU,网络/磁盘IO都不高,同样TPS也不高,这个时候可以从程序入手,分析下是否是程序执行缓慢的原因,原因大致有这么几种:
1. 有代码在串行的某件事,比如打日志(这次我遇到了因为我使用自己写的工具监控方法执行时间的关系,在性能测试时有大量打印日志和计算工作 ,导致应用程序TPS非常低,拿掉工具后TPS才恢复到一个正常的水平,当然,这不是说我的工具不好用(笑) ,有兴趣的可以看下工具的介绍,总的来说还是很好用的,工具地址: https://github.com/liuinsect/Profiler)。
2. 多线程竞争,比如,多线程环境下,锁的竞争,对象监视器的竞争,数据库,分布式缓存连接的竞争(如果使用连接池的话)等。
3. 过于冗长,复杂方法的执行,虽然JIT可以执行一定程度上的优化,但是,糟糕代码无下限,要想写得烂,总是可以的。
4. 所依赖的系统慢,比如,数据库,分布式缓存慢(当然,他们的慢有更多种可能,有时候甚至需要找到他们慢的原因,并mock掉)。
这个时候要借助visual vm等工具了。
因为很多时候我们是想在本地,去连接远程服务器上的JVM,这涉及到了远程连接JVM的问题,可以这么做:
1.首先必须在远程机器上面启动jstatd这个后台进程。它位于JDK安装路径的bin目录里面。配置java安全访问,在jstatd所在的目录的下新建文件jstatd.all.policy,在我的机器上是/usr/java/jdk1.7.0_05/bin
grant codebase “file:${java.home}/../lib/tools.jar” {
permission java.security.AllPermission;
};
注意结尾还有一个分号。
2.然后用如下命令启动jstatd:
jstatd -J-Djava.security.policy=jstatd.all.policy
正常启动没有任何输出。默认打开端口是1099,也可以通过-p 参数设置端口。
3. 在本地打开 visual vm ,输入远程服务器的IP后,即可连接了。
当然,因为只是启动了jstatd,通过visual是不能使用线程监控,CPU监控的,如果需要用到这些功能的话,还需要使用JMX去远程连接tomcat 。方法在这里:http://www.oschina.net/question/162973_105064
通过visual vm 已经可以观察到GC的情况,运行的线程数,是Block,Running 等等情况了,如果应用程序竞争激烈,应该会看到线程运行条上有一段一段的红色区域,代表线程正在被频繁阻塞,再想深入,可用通过visual vm 将线程情况dump下来(当然,也可以在应用服务器上使用jstack -m <pid>),查看线程都被哪些对象阻塞,线程的调用栈是什么样子的, 从而定位到,应用程序中哪段代码有频繁竞争,为什么竞争,是否可以优化等。
当然,除了使用visual vm 还可以使用linux上的另外一个工具 perf ,他是linux 自带的性能分析工具。可以通过它看到系统执行的性能情况,功能实在强大,比如:
1. 列出L1,L2,L3 Cache的命中率(需要硬件支持,这次我们性能测试的机器不支持它)
2. 列出系统/进程的性能统计信息 命令: perf top -p pid
3. 分析程序的整体性能 perf stat
等等, 具体可以参考这里: http://iamzhongyong.iteye.com/blog/1908118
关于perf,这次还有一个小小的故事,在测试接口的某个方法时,使用perf观察到JVM的反射相关的方法耗时开销非常高,这才想起来反射相关的代码没有对反射的结果做缓存,因此果断回去加上缓存后,看到前面的方法在perf的列表中消失,这才放下心。
总结:
通过以上介绍的性能测试的思路和工具,我们基本上可以完成一次性能测试以及部分问题的性能定位,但是往往性能问题总是隐藏得很深的,并且受各种条件的影响,比如,各个环节的配置参数,网络情况,机器情况,性能测试的工具等等,所以,性能测试的结果往往不能脱离某个环境单独比较,不同的配置,环境,应用的性能都会呈现出不同的结果,出现问题时,也需要我们从前到后,从上到下仔细分析每一个流程的执行情况,逐步通过工具协助定位,才能终找到瓶颈。总之,性能测试是一门考验耐心,细心,知识广度, 深度的活,每次遇到问题多问几个为什么,多做几次分析和验证,并尝试解决,优化它,一定会让你对系统有更多不一样的认识。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11