【闲说】性能测试

标签: 并发译文 | 发表时间:2014-07-21 20:29 | 作者:liuinsect
出处:http://ifeve.com

版权声明:本文为本作者原创文章,转载请注明出处。感谢 码梦为生| 刘锟洋 的投稿

性能测试是一件看起来不简单,操作起来确更困难的事情,我认为,每认真做一次性能测试,一定会有不同收获,而每次性能测试暴露的问题,现象都不是仅仅涉及Java,tomcat这么简单,简单说就是光会写代码是无法做好性能测试的。

那么,就趁着这次性能测试的机会,重新梳理下对linux,网络IO等基本功的认识已经就性能瓶颈的定位分享下自己的心得。

背景:

本次性能测试的目的是测试使用公司内部RPC框架开发的一套接口的性能,目的是准确的拿到接口的性能指标,当然,我也想换个角度去看待代码,比如,从性能或者对操作系统友好的角度,首先略过1万字的环境搭建过程,其实,性能测试是件非常考验细心程度的活,需要你对整个组网环境,调用关系,业务逻辑非常清晰,能正确识别出压力机,应用服务器,数据库服务器,缓存服务器各自的职责,并在可能的情况下压榨其性能极限,以及清楚明白可能对其性能造成影响的命令和操作(比如jvm启动参数中,大部分日志打印相关参数,关闭即时编译,调整GC分带的大小和比例等等)。

其次,还需要你能清楚本次测试程序的核心流程,业务逻辑,尽可能的将一些非核心的组件可能造成的影响去除掉,比如,本次测试的是RPC接口的性能和业务处理的效率,而相应涉及到的分布式缓存,数据库,则不是本次测试的重点,因此,组网时,应该尽可能将分布式缓存,数据库等机器与应用服务器放在同一个局域网网段内甚至同一台机器上,保证不会因为他们的表现而直接影响测试目标测试结果。总之,Mock掉一切非核心,不相关的因素。

测试工具/命令

因为是对RPC接口做测试(而非HTTP接口),使用loadRunner等测试工具无法满足要求,所以在测试工具的选择上,使用了jmeter。这是一款100%java实现的性能测试工具,使用方式是,继承他的AbstractJavaSamplerClient抽象类,在其runTest方法中编写测试用例即可在Jmeter的客户端中发现测试jar包,从而配置线程数后开始性能测试。具体使用请google之。
在压力机上部署好jmeter后,多线程开始执行测试用例,用例开始向应用服务器发送调用请求。这个时候设置的并发数应该尽量让压力机的CPU达到一个较高的值,比如 70%左右,jemeter提供了预热功能,必要时候可以使用预热功能将压力慢慢加大。

下面,我们借这次性能测试的机会介绍几个很好用的命令,启动后可以先到应用服务器上使用top命令,观察其CPU利用率,按数字键1,详细查看每个CPU的利用率。 理想情况,这个时候应该可以看到一定的压力。
也可以使用 vmstat命令,比如: vmstat 1  30 标示,每隔一秒打印一次统计信息,统计30秒。

打印结果类似:
talk_performance_test_1

通常主要关注r 和b 分别代表运行队列的数量和阻塞个数。理想情况应该是r比较多,b没有。
具体vmstat命令的结束可以看: http://www.cnblogs.com/ggjucheng/archive/2012/01/05/2312625.html

关注完CPU,还可以使用iostat命令 查看IO的情况,命令格式类似vmstat, iostat 1 30 表示同样的意思:每秒打印一次统计信息,打印30次后退出。

这里使用iostat -dx 1   每隔一秒打印一次磁盘的详细信息  具体可以参看这里: http://www.cnblogs.com/peida/archive/2012/12/28/2837345.html
talk_performance_test_2
可以看到io并不频繁。都是在很低 的水平上,因此IO应该不是此次性能测试的瓶颈所在。

看完vmstat,iostat,如果都不是处在很高的水平,下一个应该优先看网络,是的,对于linux还有一个iostat,使用方式与前两种不同,但是功能同样强大,可以列出应用服务器上所有tcp连接的详细信息。通常情况,可以观察下应用服务器上的TCP连接数,连接状态是否正常等来判断应用是否运行正常。
很好用的工具,动手输一下,你就会知道它的功能了。

测试目的

一般测试的目的有两个:
1. 是获取接口的性能,常用TPS,延迟,QPS等衡量。
2. 是通过性能测试,找出性能瓶颈,定位并优化它。

因此,性能测试必须要满足的一个原则是,要么把压力机跑满,要么让应用服务器的某项指标跑满,之所以说某项指标,是因为,根据应用的不同,例如:CPU密集型应用,IO密集型应用,相应的,性嫩测试的时候应该尽量让CPU利用率或者IO利用率达到一个较高的水平。

如果有一项指标没有达标,那性能瓶颈的定位过程就来了。

瓶颈定位

要定位瓶颈,首先需要知道应用服务器的哪项指标没有达到预期,是CPU利用率还是IO利用率或是都不高,这可以通过以上介绍的三个stat工具观察出来,如果没有看到哪项值比较高,至少也可以得到“都不高”的结论,而都不高的时候,或许意味着你的应用程序不像你想象的那么高效,一定,一定,在某个点上正在激烈的竞争者或者阻塞。程序会平白无故效率低下!

当然除了通过利用率,可以看到CPU或者IO的忙闲程度,有时我们还需要知道具体的数字,比如,哪种IO才算繁忙?

举个例子,这次性能测试时我使用了一个工具:ifstat,它并非系统自带的工具,需要手动安装,安装过程非常简单,自行google即可。
安装完毕后,将ifsta命令加入到path变量中,即可在全局使用ifstat命令,使用后的效果大致是这样:
talk_performance_test_3
eth0 代表了操作系统的第一张网卡。从这里可以看到此时这张网卡的读入速率是15M,出口是8M左右,而这张网卡的速率为:
talk_performance_test_4

也就是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的列表中消失,这才放下心。

总结:

通过以上介绍的性能测试的思路和工具,我们基本上可以完成一次性能测试以及部分问题的性能定位,但是往往性能问题总是隐藏得很深的,并且受各种条件的影响,比如,各个环节的配置参数,网络情况,机器情况,性能测试的工具等等,所以,性能测试的结果往往不能脱离某个环境单独比较,不同的配置,环境,应用的性能都会呈现出不同的结果,出现问题时,也需要我们从前到后,从上到下仔细分析每一个流程的执行情况,逐步通过工具协助定位,才能最终找到瓶颈。总之,性能测试是一门考验耐心,细心,知识广度, 深度的活,每次遇到问题多问几个为什么,多做几次分析和验证,并尝试解决,优化它,一定会让你对系统有更多不一样的认识。

(全文完)如果您喜欢此文请点赞,分享,评论。



您可能感兴趣的文章

相关 [性能 测试] 推荐:

mongodb性能测试

- - 数据库 - ITeye博客
1) Mongodb的非安全插入方式,在一开始插入性能是非常高的,但是在达到了两千万条数据之后性能骤减,这个时候恰巧是服务器24G内存基本占满的时候(随着测试的进行mongodb不断占据内存,一直到操作系统的内存全部占满),也就是说Mongodb的内存映射方式,使得数据全部在内存中的时候速度飞快,当部分数据需要换出到磁盘上之后,性能下降很厉害.

WebService性能测试

- - ImportNew
(本文也会在最下面通俗的介绍). 这里给一个站内大哥的讲解: http://www.cnblogs.com/Leo_wl/archive/2010/05/20/1740205.html. 简单点就是测试WebService的一个工具. 官网地址: http://www.soapui.org/. ps:官网是英语的,如果你英语不好的话可以使用谷歌浏览器或360极速浏览器,它可以自动把英文转换成中文.

性能测试工具 CBenchmark

- lele - 开源中国社区最新软件
CBenchmark—-CharlesCui’s Benchmark 这是我实现的一款性能测试工具,之前在工作中常用LoadRunner之类的工具来完成性能测试,但受限于LR极其昂贵的Lisence以及难以定制的SDK,于是我用C/C++实现了这个工具,并借助Linux系统对线程和进程的良好调度,可以实现极高的并发压力.

浏览器性能测试

- - Taobao QA Team
浏览器作为一个浏览网页的平台,自身的性能直接影响网页的解析速度、渲染,而浏览器的性能一般又是由浏览器的内核来决定. 虽然浏览器的评测方法有很多,但是权威的浏览器性能测试方法主要有以下几种:. Acid3测试是检测浏览器与Web标准兼容性的主要方法,也是目前行业中最权威的测试. Acid3是由网页标准计划小组(Web Standards Project, WaSP)设计,测试焦点集中在ECMAScript、DOM Level 3、Media Queries和data: URL,浏览器开启 http://acid3.acidtests.org/测试页面后,页面会不断加载功能、直接给予分数.

【闲说】性能测试

- - 并发编程网 - ifeve.com
版权声明:本文为本作者原创文章,转载请注明出处. 感谢 码梦为生| 刘锟洋 的投稿. 性能测试是一件看起来不简单,操作起来确更困难的事情,我认为,每认真做一次性能测试,一定会有不同收获,而每次性能测试暴露的问题,现象都不是仅仅涉及Java,tomcat这么简单,简单说就是光会写代码是无法做好性能测试的.

Android应用性能测试

- - CSDN博客推荐文章
java虚拟机有内存使用上限的限制. adb shell进入手机,这此参数被纪录在/system/build.prop中,如果想直接查看可以使用adb shell getprop. 单个应用程序最大内存限制,超过这个值会产生OOM. 单个java虚拟机最大的内存限制,超过这个值会产生OOM. android程序内存一般限制在16M,当然也有24M的,而android程序内存被分为2部分:.

web性能测试指标

- - 研发管理 - ITeye博客
Web性能测试的部分概况一般来说,一个Web请求的处理包括以下步骤:. (2)web server接受到请求,进行处理;. (3)web server向DB获取数据;. (4)webserver生成用户的object(页面),返回给用户. 给客户发送请求开始到最后一个字节的时间称为响应时间(第三步不包括在每次请求处理中).

node.js调研与服务性能测试

- lostsnow - 淘宝数据平台与产品部官方博客 tbdata.org
这几天对nodejs进行了一下简单的调研. 考虑到今后的应用场景, 实现了一个简单的memcache代理服务.. 内部维护了一个50连接的简单连接池, 通过长连接与memcache服务器相连.. 同时对外提供socket代理服务与http restful服务. 测试使用编译安装的node.js v0.3.1,未使用任何第三方modules.

HBase随机读写性能测试

- jiaosq - NoSQLFan
本文转载自淘宝网BlueDavy同学的博客,文章基于淘宝对HBase的大量应用,给出了一个HBase的随机读写性能测试结果,对测试环境、配置及性能参数分析都有较详细的描述,推荐给各位NoSQL Fans. 根据最近生产环境使用的经验,更多的项目的采用,以及采用了更加自动的测试平台,对HBase做了更多的场景的测试,在这篇blog中来分享下纯粹的随机写和随机读的性能数据,同时也分享下我们调整过后的参数.

NoSQL性能测试白皮书

- - 博客园_知识库
  最近,bankmark公司针对目前市面上流行的NoSQ数据库SequoiaDB、Cassandra、MongoDB进行了详细的性能测试,InfoQ经授权发布中文版白皮书.   作为一项快速发展的极具创新性的IT技术,NoSQL 技术在大数据和实时网页应用中的运用在最近几年呈现了大量的增长. 因为NoSQL数据库的存储允许更灵活的开发方式和执行方式,这些NoSQL数据库能够在许多的工商业应用领域很好地替代传统关系型数据库(RDBMS).