系统压测时CPU达到100%但是QPS却很低

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了系统压测时CPU达到100%但是QPS却很低相关的知识,希望对你有一定的参考价值。

参考技术A 线上系统,正在做压力测试,刚开始10并发进行压测,cpu压到了100%但是系统最大qps才200多。通过JVM监控查看JVM younggc很频繁,fullGC数量为零。

cpu 达到100% 则先看cpu使用率最高是哪个进程,可以直接通过linux命令 top查看,找到对应的进程ID,发现正是压测的java系统进程ID,找到进程ID后,然后在查找该进程下CPU使用率最高是哪个线程,可以通过top -p 进程ID -H 命令显示线程使用cpu信息,效果如下:

图片中PID列则为十进制显示的线程ID,然后转换为16进制通过jstack 系统进程ID | grep 16进制线程ID 可以找到对应的线程信息如下,也就是该线程占用了一半左右的cpu

Finalizer线程是个单一职责的线程。这个线程会不停的循环等待java.lang.ref.Finalizer.ReferenceQueue中的新增对象。一旦Finalizer线程发现队列中出现了新的对象,它会弹出该对象,调用它的finalize()方法,将该引用从Finalizer类中移除,因此下次GC再执行的时候,这个Finalizer实例以及它引用的那个对象就可以回垃圾回收掉了。
说明Finalizer的队列中有许多的等待回收的垃圾对象,可以通过命令查看等待回收的对象都有哪些;
jmap -finalizerinfo 进程ID
执行命令后显示结果如下

发现有好多的自定义对象,通过类名可以看到这些对象都是通过CGLIB动态代理创建的,而这些动态代理类都默认实现了finalize方法,导致这些对象在进行垃圾回收时必须先要执行finalize方法,所以都积压到了finalizer的队列中。

1.不要使用cglib来给那些需要频繁进行垃圾回收的对象创建动态代理,这些对象大量创建的同时,也会创建相等数量的动态代理对象,使得内存占用迅速增长,并且不断进行垃圾回收,由于代理类重写了finalize方法,给垃圾回收带来了额外的压力。
2.尽量能够复用对象,不要每次都new一个对象

JMeter压测时如何在达到给定错误数量后停止测试

问题 在做接口自动化性能测试时,偶尔会有不稳定的因素导致请求断言失败。JMeter线程组对错误处理有两种常用处理方式:继续或停止测试 因某些原因极个别错误不影响压测结果是可以忽略的,若选择继续测试,当真正发生服务崩溃时也会一直压下去这不是我们想要的,那么在压测过程中怎样才能在达到指定的累计错误数量后

以上是关于系统压测时CPU达到100%但是QPS却很低的主要内容,如果未能解决你的问题,请参考以下文章

压测出现各种奇葩问题,求围观

JMeter压测时如何在达到给定错误数量后停止测试

压测基础

读书笔记:压测与预案

2017双11-开启智能全链路压测之路

压测模型及其优缺点