性能测试常见问题总结

性能测试典型问题记录

硬件上的性能瓶颈

一般指的是CPU、内存、I/O读写速率,磁盘空间方面的问题。

网络上的性能瓶颈:

一般指的网络带宽,网络波动,延时,丢包等。

应用程序上的性能瓶颈

一般指的是开发人员新开发出来的应用程序。

例如,程序架构规划不合理,程序本身设计有问题(串行处理、请求的处理线程不够),造成系统在大量用户方位时性能低下而造成的瓶颈。

数据库的性能瓶颈

一般指的是数据库索引,锁,表空间,慢sql,数据量等影响。

中间件的性能瓶颈:

比如:超时设置,线程池设置,缓存策略,最大连接数,负载均衡策略等等。

常见问题

一、容量测试过程中cpu过高

1、用top实时监控cpu使用情况。一般情况下cpu使用率指标是不能超过70%,压测过程中, cpu使用率过高,超过70%以上。

2、分析是use cpu过高还是sys cpu过高,常见的是use cpu使用过高。

3、如果是use cpu使用过高,先把消耗cpu最多的进程找出来(top命令,vmstat),再找到该进程下消耗cpu过高的线程(top -H -p 进程号)或者(ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu命令查找占用cpu高的线程),再把该线程转换成16进制(printf “%x\n” 线程号),再用jstack命令来dump线程栈,看这个线程栈在调用什么东西导致use cpu过高(jstack 进程号 | grep 16进制的线程号)。

4、如果是sy cpu过高,首先查看磁盘繁忙程度、磁盘的队列(iostat、nmon),查看在没有做压测的情况下,sy cpu的使用情况,如果还是较高,则使用strace查看系统内核调用情况,找到系统耗cpu的原因(strace -p 进程号)。

二、内存溢出(堆溢出、栈溢出、持久代溢出)

1、堆内存溢出

稳定性压测一段时间后,LR报错,日志报java.lang.OutOfMemoryError.Java heap space。
首先检查JVM配置参数,如果参数设置太小,则需要修改JVM参数,修改xms,xmx,调整堆内存参数,一般是增加堆内存。
用jmap -histo pid> test.txt命令dump堆内存使用情况,并且保存到test.txt文件中,查看堆内存排名前20个对象,看是否有自己应用程序的方法,从最高的查起,如果有则检查该方法是什么原因造成堆内存溢出,排查可能的原因。
如果前20里没有自己的方法,则用命令:jmap -dump:live,format=b,file=test.dump pid生成dump文件,然后使用MAT进行分析dump下来的堆内存,分析导致内存溢出的方法。
如果怀疑是内存泄漏,也可以使用JProfiler连上服务器在开始跑压测,运行一段时间后点击“Mark Current Values”,后续的运行就会显示增量,这时执行一下GC,观察哪个类没有彻底回收,基本就可以判断是这个类导致的内存泄漏。
解决:优化代码,对象使用完毕,需要置成null。

2、栈内存溢出

稳定性压测一段时间后,LR报错,日志报Java.Lang.StackOverflowError。
原因可能是递归没返回,循环调用造成。
修改jvm参数,将xss参数改大,增加栈内存。
栈溢出一定是做批量操作引起的,减少批处理数据量。
3、持久代溢出

稳定性压测一定时间后,日志报Java.Lang.OutOfMenoryError.PermGen Space。
这种原因是由于类、方法描述、字段描述、常量池、访问修饰符等一些静态变量太多,将持久代占满导致持久代溢出。
修改jvm配置,将XX:MaxPermSize参数调大。尽量减少静态变量。
系统内存溢出
现象:压测执行一段时间后,日志中有报错信息:java.lang.OutOfMemoryError: unable to create new native thread。

原因:操作系统没有足够的资源来产生这个线程造成的。系统创建线程时,除了要在Java堆中分配内存外,操作系统本身也需要分配资源来创建线程。因此,当线程数量大到一定程度以后,堆中或许还有空间,但是操作系统分配不出资源来了,就出现这个异常了。

解决:

(1)减少堆内存
(2)减少线程数量
(3)如果线程数量不能减少,则减少每个线程的堆栈大小,通过-Xss减小单个线程大小,以便能生产更多的线程。

三、线程死锁

现象:容量测试压测一段时间后,LR报连接超时错误。

原因:造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时的错误。

分析:

使用jstack命令查看Java进程下所有线程的情况(jstack -l 进程号),查询线程栈里有没有block,如果有的话就是线程死锁,找到死锁的线程,分析对应的代码。如果大量线程都是Waiting状态,则需要去关注数据库和中间件,可能会有排队情况。
查看TCP连接情况(netstat -an |awk '/tcp/
Unknown macro: {print $6}

'|sort|uniq -c ),用netstat -nat|grep -i “端口”|grepTIME_WAIT|wc -l命令查看TIME_WAIT情况,如果TIME_WAIT的值很大并且一直增加的话,说明tcp不能正常释放,会造成响应时间增加。

四、数据库死锁

现象:容量测试压测一段时间后,LR报连接超时错误。

原因:造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。

分析:查看数据库日志,看有没有死锁的情况:show engine innodb status\G。数据库日志中搜索block,能搜到block的话就是存在数据库死锁,找到日志,查看对应的sql,优化造成死锁的sql。

五、数据库连接池不释放

现象:容量测试压测一段时间后,LR报连接超时错误。

原因:造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。

解决:
去mysql数据库查看应用程序到数据库的连接有多少个

呈现代码宏出错: 参数’com.atlassian.confluence.ext.code.render.InvalidValueException’的值无效

通过命令:

show variables like ‘%max_connections%’; 查询设置的最大连接数;

show status like 'Threads%'查询当前的连接数是多少

show processlist/show full processlist;

如果当前连接数大于等于最大连接数,说明数据库连接池被占满,需要把最大连接数修改大一点

呈现代码宏出错: 参数’com.atlassian.confluence.ext.code.render.InvalidValueException’的值无效

一般在/etc/my.cnf里面修改 max_connections = xxxx

或通过命令:set global max_connections=xxxx 进行设置

复测看是否还会出现问题,如果出现去数据库查看连接,如果当前连接数大于等于最大连接数,则可以确定是数据库连接池不释放导致的。查看代码,数据库连接部分是不是有创建连接但是没有关闭连接的情况。基本就是这种情况导致的,修改代码即可。

六、数据库连接失效

现象:No operations allowed after connection closed,日志发现此报错,问题出在mysql。

原因:数据库的连接被创建后,如果没有手动关闭连接,mysql默认是8小时之后回收连接,如果超过8个小时,应用程序不去访问数据库,数据库就会断掉连接,当程序调用此连接时,到数据库才发现,此连接已经失效了,这时访问就会抛出此异常。

解决:涉及两个参数interactive_timeout和wait_timeout,默认是8小时,延长时间。修改mysql配置文件:vi /etc/my.cnf, 在[mysqld]区域添加这两项,然后重启数据库解决。

七、TPS上不去

1、网络带宽

在压力测试中,有时候要模拟大量的用户请求,如果单位时间内传递的数据包过大,超过了带宽的传输能力,那么就会造成网络资源竞争,间接导致服务端接收到的请求数达不到服务端的处理能力上限。可以通过:直接复制文件传输到另一台服务器 初步查看网速是否达到网络带宽上限(scp -r -P 端口号 root@123.123.123.123:/root/

如网络带宽为100M时,可传输的最大网速为 12M/s 左右。

2、连接池

最大连接数太少,造成请求等待。连接池一般分为服务器中间件连接池(比如Tomcat)和数据库连接池(或者理解为最大允许连接数也行)。

3、垃圾回收机制

从常见的应用服务器来说,比如Tomcat,如果堆内存设置比较小,就会造成新生代的Eden区频繁的进行Young GC,老年代的Full GC也回收较频繁,那么对TPS也是有一定影响的,因为垃圾回收时通常会暂停所有线程的工作。

4、数据库

高并发情况下,如果请求数据需要写入数据库,且需要写入多个表的时候,如果数据库的最大连接数不够,或者写入数据的SQL没有索引没有绑定变量,抑或没有主从分离、读写分离等,就会导致数据库事务处理过慢,影响到TPS。

5、硬件资源

包括CPU(配置、使用率等)、内存(占用率等)、磁盘(I/O、页交换等)。

6、压力机

比如Jmeter和Loadrunner,单机负载能力有限,如果需要模拟的用户请求数超过其负载极限,也会间接影响TPS(这个时候就需要进行分布式压测来解决其单机负载的问题)。

7、业务逻辑

业务解耦度较低,较为复杂,整个事务处理线被拉长也会导致TPS上不去。

八、TPS波动大

出现TPS波动较大问题的原因一般有网络波动其他服务资源竞争以及垃圾回收问题这三种。

性能测试环境一般都是在内网或者压测机和服务在同一网段,可通过监控网络的出入流量来排查;(局域网可以不考虑)

其他服务资源竞争也可能造成这一问题,可以通过Top命令或服务梳理方式来排查在压测时是否有其他服务运行导致资源竞争;

垃圾回收问题相对来说是最常见的导致TPS波动的一种原因,可以通过GC监控命令来排查(jstat -gc PID 300 10)

九、压测过程中TPS不断下降,CPU使用率不断降低

原因:一般来说,出现这种问题的原因是因为线程block导致,当然不排除其他可能;

解决:如果是线程阻塞问题,修改线程策略,然后重新验证即可;

十、响应时间长,SQL使用不合理

压测过程中,LR结果显示事务响应时间长

针对mysql:首先打开数据库的慢查询,通过命令找到执行比较久的SQL语句:mysql dump slow;分析是由于索引问题还是其他问题。

针对oracle:我们可以打AWR报告,通过报告分析,主要关注SQL ordered by Elapsed Time和SQL ordered by CPU Time两项,找出数据库sql问题。

十一、服务器压力不均衡(相差1%-2%是正常的)

一般情况下,多台服务器资源相差不大,如果压测的时候,多台应用服务器中只有一台cpu超过60%,其他的都在60%以下。
通过top查看除了应用进程本身,是否还有其他耗cpu较高的进程。
查看cpu超过60%的服务器是否有定时任务。
查看是否存在压力机瓶颈。
是否存在带宽瓶颈(局域网不考虑此问题)。
查看部署的版本,配置是否一样。
可能别人也在用这些AP,因为同一台物理机上有很多虚拟机,因为别人先用,资源被别人先占了。
查看负载均衡策略,

十二、压测过程中,出现大量5xx错误

现象:在压测过程中,服务器返回500错误

分析:500错误表示服务器内部错误,出现此错误时,我们首先查看服务器日志,通过错误日志信息定位具体错误的原因,如果出现get null from pool,说明数据库成为瓶颈,连接数不够导致,此时可以通过调整数据库连接池大小解决。

现象:在压测过程中,服务器返回502错误

分析:502一般是网关错误,同时nginx中会出现Connection reset by peer,出现此类报错的常见原因有:并发数大于服务端最大连接数,服务端会将其中一些连接关闭掉。

学习安排上

如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

在这里插入图片描述

视频文档获取方式:

这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片进群即可自行领取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值