如何做性能测试

性能优化的常用概念
吞吐量(TPS):每秒完成事物数,通常TPS越高越好。
响应时间:即从请求发出去到收到系统返回的时间,响应时间一般不取平均值,而是要去掉不稳定的值后再取平均值,如常用的90%响应时间。
错误率:错误请求数与总请求数之比。随着压力的增加,有可能出现处理请求处理不过来,这时错误数会不断增加。
这三者有极大的关联:吞吐量增加时,响应时间可能增加,错误率也有可能增加。

性能调优的思路
一般情况,调优需要有个前提条件,即无论是用线上的真是流水还是线下的压力测试让问题扩大化,明显化,根据这些比较明显的现象去判断问题,收集证据去初判结果成了,然后分析现象产生的原因,并尝试解决问题。
第一步:性能摸底测试
对于欣赏的系统或有过较大代码改动的系统来说,做一次摸底测试时很有必要的。一般来说,摸底测试是一次对单机的压力测试。压力测试可以帮助你大概搞清楚系统的极限TPS是多少,在压力上来时有没有暴露一些错误活着问题,系统大致的资源占用情况是什么,系统可能出现的瓶颈在哪。

第二步:定义性能测试目标
性能指标一般是吞吐量、90%响应时间、错误率,同时还要关注CPU使用情况,内存使用情况,磁盘使用情况,网络带宽等。

第三步:性能分析
一、CPU分析:针对cpu的监控,可以使用top或vmstat两个命令,详细说明top参考(http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/top.html),vmstat参考(http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/vmstat.html)
$top
top - 09:14:56 up 264 days, 20:56, 1 user, load average: 0.02, 0.04, 0.00
Tasks: 87 total, 1 running, 86 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.2%st
Mem: 377672k total, 322332k used, 55340k free, 32592k buffers
Swap: 397308k total, 67192k used, 330116k free, 71900k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 2856 656 388 S 0.0 0.2 0:49.40 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 7:15.20 ksoftirqd/0
4 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/

如果us过高:
a.代码问题:比如一个耗时的循环不加sleep,或者在一些cpu密集计算(如xml解析,加解密,加解压,数据计算)时没处理好。

b.gc频繁:一个比较容易遗留的问题就是gc频繁时us容易过高,因为垃圾回收属于大量计算的过程。gc频繁带来的cpu过高长伴有内存的大量波动,通过配合内存来判断并解决该问题更好。
那如何定位us过高的线程并查看他的状态呢?
(1) top命令找到消耗us过高的pid
(2) top -Hp pid 找到对应的线程tid
(3) printf %x tid 转为16进制tid16
(4) jstack pid | grep -C 20 tid16 即可查到该线程堆栈

wa 过高
wa 过高说明等待io的cpu占用较多。io wait引起的sy过高指的是io不停的wait然后唤醒,因为数量较大,导致上下文切换较多,强调的是动态的过程;而io wait引起的wa过高指的是io wait 的线程占用比较多,cpu切换到这个线程是io wait,到那个线程也是io wait,于是总cpu就是wait占用比较高。

id 过高
id%是空闲CPU时间百分比,如果这个值过低,表明系统CPU存在瓶颈;但id高说明资源未完全利用,或压测不到位。

二、内存分析:关于java应用的内存,通常只关注jvm内存,但有些特殊情况也需要关注物理内存。关于jvm内存,常见工具有jstat(http://blog.csdn.net/fenglibing/article/details/6411951),jmap(http://www.cnblogs.com/ggjucheng/archive/2013/04/16/3024986.html),pidstat(https://linux.cn/article-4257-1.html),vmstat,top等
jvm内存分析
异常gc:
a.程序问题:通常gc发生意味着有一块区域空间不足而触发gc。而许多导致异常gc的情况通常是持有了不必要的引用而没有及时释放,比如像cache这样的地方就容易处理不好导致内存泄漏引发异常gc。
b.jvm配置问题:程序是正常的,但没有配置合适的gc参数导致异常gc,这种情况通常需要调优gc参数或堆代大小参数。
c.Full gc发生的情况:
(1) 永久代满了
(2) 老年代满了

OOM:
a.OOM经常伴随着异常gc,之所以单独拿出来讲,是因为他的危害更大一些,异常gc顶多是收集速度过快或回收不了内存,但是起码有个缓冲时间,但是如果出了OOM问题就大了。至于各种类型的OOM如何区分,如何发生,参考(http://www.jianshu.com/p/2fdee831ed03)
b.heap区,对象创建过多或持有太多无效引用(泄漏)活着堆内存分配不足。使用jmap找到内存中对象的分布,使用ps找到相应进程及初始内存配置。
c.stack区,不正确的递归调用。
d.perm区,初始加载包过多,分配内存不足。
e.堆外内存区,分配ByteBuffer未释放导致。

三、IO分析:IO分为网络IO和文件IO,针对网络IO比较有用的工具有sar(https://linuxstory.org/generate-cpu-memory-io-report-sar-command/),netstat(https://linux.cn/article-2434-1.html)。netstat是一个比较厉害的命令,可以助于排查很多问题。针对文件io的工具有pidstat,iostat(http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/iostat.html)
文件IO
a.从技术上来说,对于大文件IO可以采取的措施是异步批处理,采用异步方式用于累计buffer,采用批处理能够让磁盘寻道连续从而更加快速

网络IO:网络IO的问题较为复杂,仅举几个常见的
a.大量TIME_WAIT。根据TCP协议,主动发起关闭连接的那一方,关闭了自己这端的连接后再收到被动发起关闭的那一方的关闭请求后,会将状态变为TIME_WAIT,并等待2MSL,目的就是等待自己的回执发送到对方。如果在服务器上发现大量TIME_WAIT,说明服务器主动断开了连接,什么情况下服务器会主动断开连接,很可能是客户端忘记了断开连接,所以一个典型的案例就是jdbc连接忘记关闭,则数据库服务器可能会出现大量的TIME_WAIT状态。
b.大量CLOSE_WAIT。CLOSE_WAIT状态,在收到主动关闭连接的一方发出关闭连接后,被动关闭的一方进入CLOSE_WAIT状态,如果这个时候被卡出来没有进行后续关闭,则会出现大量CLOSE_WAIT。什么时候会被卡住呢,举几个例子,比如刚刚的忘记关闭数据库连接,在应该服务器这端,大量的浏览器请求进来,由于没有连接池连接被卡住,这时候浏览器等待一定时间超时发送关闭连接请求。因此在应用服务器出现大量的CLOSE_WAIT。另一个例子是httpclient的坑,在调用response.getEntity()前都不会做inputStream.close(),如果在调用response.getEntity()前就返回了,就出问题了。这个例子可以参考(http://blog.csdn.net/shootyou/article/details/6615051)

第四步:优化后并重新测试验证

 

 

性能测试资料:
性能调优思路 http://www.voidcn.com/blog/bigtree_3721/article/p-5786972.html
linux下性能监控命令 http://linuxtools-rst.readthedocs.io/zh_CN/latest/advance/index.html
关于JVM CPU资源占用过高的问题排查 http://my.oschina.net/shipley/blog/520062
java排查工具 http://my.oschina.net/feichexia/blog/196575
jvm参数调优 http://www.cnblogs.com/java-zhao/archive/2016/02/08/5185092.html
java linux系统调优工具 https://www.ibm.com/developerworks/cn/java/j-lo-performance-tuning-practice/
gc优化的一些思路 http://mm.fancymore.com/reading/gc%E4%BC%98%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%9D%E8%B7%AF.html
性能优化的思路和步骤 http://www.uml.org.cn/j2ee/201602013.asp
性能调优攻略 http://coolshell.cn/articles/7490.html
JVM性能调优入门 http://www.jianshu.com/p/c6a04c88900a
JVM性能调优 http://blog.csdn.net/chen77716/article/details/5695893
Tomcat性能优化 https://yq.aliyun.com/articles/38861?utm_campaign=wenzhang&utm_medium=article&utm_source=QQ-qun&2017323&utm_content=m_14698

posted @ 2018-09-30 15:08  sssss-T  阅读(145)  评论(0)    收藏  举报