性能测试常见瓶颈分析及调优⽅法
性能分析与调优如何下⼿,先从硬件开始,还是先从代码或数据库。从操作系统(CPU调度,内存管理,进程调度,磁盘I/O)、⽹络、协议(HTTP, TCP/IP ),还是从应⽤程序代码,数据库调优,中间件配置等⽅⾯⼊⼿。
单⼀个中间件⼜分web中间件(apache 、IIS),应⽤中间件(tomcat 、weblogic 、webSphere )等,虽然都是中间件,每⼀样拎出来往深了学都不是⼀朝⼀⼣之功。但调优对于每⼀项的要求⼜不仅仅是“知道”或“会使⽤”这么简单。起码要达到“如何更好的使⽤”。
常看到性能测试书中说,性能测试不单单是性能测试⼯程师⼀个⼈的事⼉。需要DBA 、开发⼈员、运维⼈员的配合完成。但是在不少情况下性能测试是由性能测试⼈员独⽴完成的,退⼀步就算由其它⼈员的协助,了解系统架构的的各个模块对于⾃⾝的提⾼也有很⼤帮助,同时也更能得到别⼈的尊重。
再说性能调优之前,我们有必要再提⼀下进⾏测试的⽬的,或者我们进⾏性能测试的初衷是什么?
能⼒验证:验证某系统在⼀定条件具有什么样的能⼒。
能⼒规划:如何使系统达到我们要求的性能能⼒。
应⽤程序诊断:⽐如内存泄漏,通过功能测试很难发现,但通过性能测试却很容易发现。
性能调优:满⾜⽤户需求,进⼀步进⾏系统分析出瓶颈,优化瓶颈,提⾼系统整体性能。
⼀般系统的瓶颈
sql优化的几种方式性能测试调优需要先发现瓶颈,那么系统⼀般会存在哪些瓶颈:
硬件上的性能瓶颈:
⼀般指的是CPU、内存、磁盘I/O ⽅⾯的问题,分为服务器硬件瓶颈、⽹络瓶颈(对局域⽹可以不考虑)、服务器操作系统瓶颈(参数配置)、中间件瓶颈(参数配置、数据库、web服务器等)、应⽤瓶颈(SQL 语句、数据库设计、业务逻辑、算法等)。
应⽤软件上的性能瓶颈:
⼀般指的是应⽤服务器、web 服务器等应⽤软件,还包括数据库系统。
例如:中间件weblogic 平台上配置的JDBC连接池的参数设置不合理,造成的瓶颈。
应⽤程序上的性能瓶颈:
⼀般指的是开发⼈员新开发出来的应⽤程序。
例如,程序架构规划不合理,程序本⾝设计有问题(串⾏处理、请求的处理线程不够),造成系统在⼤量⽤户访问时性能低下⽽造成的瓶颈。
操作系统上的性能瓶颈:
⼀般指的是windows、UNIX、Linux等操作系统。
例如,在进⾏性能测试,出现物理内存不⾜时,虚拟内存设置也不合理,虚拟内存的交换效率就会⼤⼤降低,从⽽导致⾏为的响应时间⼤⼤增加,这时认为操作系统上出现性能瓶颈。
⽹络设备上的性能瓶颈:
⼀般指的是防⽕墙、动态负载均衡器、交换机等设备。
例如,在动态负载均衡器上设置了动态分发负载的机制,当发现某个应⽤服务器上的硬件资源已经到达极限时,动态负载均衡器将后续的交易请求发送到其他负载较轻的应⽤服务器上。在测试时发现,动态负载均衡器没有起到相应的作⽤,这时可以认为⽹络瓶颈。
性能测试出现的原因及其定位⼗分复杂,这⾥只是简单介绍常见的⼏种瓶颈类型和特征,⽽性能测试所需要做的就是根据各种情况因素综合考虑,然后协助开发⼈员\DBA\运维⼈员⼀起定位性能瓶颈。
⼀般性能问题调优的步骤:
步骤⼀:确定问题
应⽤程序代码:在通常情况下,很多程序的性能问题都是写出来的,因此对于发现瓶颈的模块,应该⾸先检查⼀下代码。
数据库配置:经常引起整个系统运⾏缓慢,⼀些诸如oracle 的⼤型数据库都是需要DBA进⾏正确的参数调整才能投产的。
操作系统配置:不合理就可能引起系统瓶颈。
硬件设置:硬盘速度、内存⼤⼩等都是容易引起瓶颈的原因,因此这些都是分析的重点。
⽹络:⽹络负载过重导致⽹络冲突和⽹络延迟。
步骤⼆:确定问题
当确定了问题之后,我们要明确这个问题影响的是响应时间吞吐量,还是其他问题?是多数⽤户还是少数⽤户遇到了问题?如果是少数⽤户,这⼏个⽤户与其它⽤户的操作有什么不⽤?系统资源监控的
结果是否正常?CPU的使⽤是否到达极限?I/O 情况如何?问题是否集中在某⼀类模块中? 是客户端还是服务器出现问题? 系统硬件配置是否够⽤?实际负载是否超过了系统的负载能⼒? 是否未对系统进⾏优化?
通过这些分析及⼀些与系统相关的问题,可以对系统瓶颈有更深⼊的了解,进⽽分析出真正的原因。
步骤三:确定调整⽬标和解决⽅案
提⾼系统吞吐量,缩短响应时间,更好地⽀持并发。
步骤四:测试解决⽅案
对通过解决⽅案调优后的系统进⾏基准测试。(基准测试是指通过设计科学的测试⽅法、测试⼯具和测试系统,实现对⼀类测试对象的某项性能指标进⾏定量的和可对⽐的测试)
步骤五:分析调优结果
系统调优是否达到或者超出了预定⽬标?系统是整体性能得到了改善,还是以系统某部分性能来解决其他问题。调优是否可以结束了。
最后,如果达到了预期⽬标,调优⼯作就基本可以结束了。
_
下⾯算是⼀个技巧,如⾯试官问到⼀个性能问题假设,我不知道性能问题出在哪⼉时,可以按照这个思路回答
· 查瓶颈时按以下顺序,由易到难。
服务器硬件瓶颈—〉⽹络瓶颈(对局域⽹,可以不考虑)—〉服务器操作系统瓶颈(参数配置)—〉中间件瓶颈(参数配置,数据库,web 服务器等)—〉应⽤瓶颈(SQL语句、数据库设计、业务逻辑、算法等)
注:以上过程并不是每个分析中都需要的,要根据测试⽬的和要求来确定分析的深度。对⼀些要求低的,我们分析到应⽤系统在将来⼤的负载压⼒(并发⽤户数、数据量)下,系统的硬件瓶颈在哪⼉就够了。
· 分段排除法 很有效
性能测试调优应该注意的要点:
要点1: 在应⽤系统的设计开发过程中,应始终把性能放在考虑的范围内。
要点2:确定清晰明确的性能⽬标是关键。
要点3: 必须保证调优后的程序运⾏正确。
要点4: 系统的性能更⼤程度上取决于良好的设计,调优技巧只是⼀个辅助⼿段。
要点5: 调优过程是迭代渐进的过程,每⼀次调优的结果都要反馈到后续的代码开发中去。
要点6: 性能调优不能以牺牲代码的可读性和可维护性为代码。
下⾯让我们来聊聊性能测试过程中的⼀些注意事项,以及常见的⼀些性能缺陷表现及如何进⾏定位分析并且调优。。。
⼀、注意事项
1、断⾔
在压测时,为了判断发送的请求是否成功,⼀般会通过对请求添加断⾔来实现。使⽤断⾔时,建议遵循如下规范:
①、断⾔内容尽量以status/code、msg/message来判断(当然前提是接⼝设计遵循Restful规范)
Jmeter⽰例:
阿⾥云PTS:
如果使⽤的是PTS压测,则断⾔设置中,以code/status、msg/message等于对应的值为准;
②、尽可能不要将所有的Response Body内容作为断⾔判断的内容,这样很可能会导致⼤量的“断⾔”失败;
PS:然后很遗憾的是,见过很多做压测的童鞋,断⾔内容以整个响应参数内容做断⾔,导致⼤量的报错。
2、成功率
⼀般在性能测试中,我们都追求99.99%的成功率,但在实际的测试过程中,为了尽可能覆盖代码逻辑,在准备阶段会尽可能的准备较多的热点数据去做到覆盖。
这样的话,我们所关注的成功率指标,就要分为如下两种:
①、事务成功率
事务成功率在某些时候也可以视为请求成功率,在断⾔判断时以code/status等内容来作为请求是否成功的衡量依据;
②、业务成功率
实际的业务场景中,所谓的成功率,并不能仅根据返回的code/status来判断。⽐如:⼀个查询请求,⽆论是返回正确的查询结果还是由于对应数据返回空,这个请求都是成功的。
对应的响应参数可能是:{"status":"200","message":"success"};也可能是:{"status":"200","message":"暂⽆对应结果"}。
PS:在性能测试过程中,考虑到业务成功率和请求成功率的不同指标,结合断⾔内容,需要灵活设置断⾔的⽅式(当然,我依然建议遵循如上的2点断⾔规范)!
⼆、常见性能瓶颈解析及调优⽅案
在性能测试中,导致性能出现瓶颈的原因很多,但通过直观的监控图表现出来的样⼦,根据出现的频次,⼤概有如下⼏种:性能瓶颈出现频次具体表现
⾼TPS波动较⼤
⾼⾼并发下⼤量报错
中集类系统,各服务节点负载不均衡
中并发数不断增加,TPS上不去,CPU耗⽤不⾼
低压测过程中TPS不断下降,CPU使⽤率不断降低
下⾯对常见的⼏种性能瓶颈原因进⾏解析,并说说常见的⼀些调优⽅案:
1、TPS波动较⼤
原因解析:出现TPS波动较⼤问题的原因⼀般有⽹络波动、其他服务资源竞争以及垃圾回收问题这三种。
性能测试环境⼀般都是在内⽹或者压测机和服务在同⼀⽹段,可通过监控⽹络的出⼊流量来排查;
其他服务资源竞争也可能造成这⼀问题,可以通过Top命令或服务梳理⽅式来排查在压测时是否有其他服务运⾏导致资源竞争;
垃圾回收问题相对来说是最常见的导致TPS波动的⼀种原因,可以通过GC监控命令来排查,命令如下:
1 # 实时打印到屏幕
2 jstat -gc PID 300 10
3 jstat -gcutil PID 300 10
4 # GC信息输出到⽂件
5 jstat -gc PID 1000 120 >>/
6 jstat -gcutil PID 1000 120 >>/
调优⽅案:
⽹络波动问题,可以让运维同事协助解决(⽐如切换⽹段或选择内⽹压测),或者等到⽹络较为稳定时候进⾏压测验证;
资源竞争问题:通过命令监控和服务梳理,出压测时正在运⾏的其他服务,通过沟通协调停⽌该服
务(或者换个没资源竞争的服务节点重新压测也可以);
垃圾回收问题:通过GC⽂件分析,如果发现有频繁的FGC,可以通过修改JVM的堆内存参数Xmx,然后再次压测验证(Xmx最⼤值不要超过服务节点内存的50%!)
2、⾼并发下⼤量报错
原因解析:出现该类问题,常见的原因有短连接导致的端⼝被完全占⽤以及线程池最⼤线程数配置较⼩及超时时间较短导致。
调优⽅案:
短连接问题:修改服务节点的tcp_tw_reuse参数为1,释放TIME_WAIT scoket⽤于新的连接;
线程池问题:修改服务节点中容器的l⽂件中的配置参数,主要修改如下⼏个参数:
# 最⼤线程数,即服务端可以同时响应处理的最⼤请求数
maxThreads="200"
# Tomcat的最⼤连接线程数,即超过设定的阈值,Tomcat会关闭不再需要的socket线程
maxSpareThreads="200"
# 所有可⽤线程耗尽时,可放在请求等待队列中的请求数,超过该阈值的请求将不予处理,返回Connection refused错误
acceptCount="200"
# 等待超时的阈值,单位为毫秒,设置为0时表⽰永不超时
connectionTimeout="20000"
3、集类系统,各服务节点负载不均衡
原因解析:出现这类问题的原因⼀般是SLB服务设置了会话保持,会导致请求只分发到其中⼀个节点。
调优⽅案:如果确认是如上原因,可通过修改SLB服务(F5/HA/Nginx)的会话保持参数为None,然后再次压测验证;
4、并发数不断增加,TPS上不去,CPU使⽤率较低
原因解析:出现该类问题,常见的原因有:SQL没有创建索引/SQL语句筛选条件不明确、代码中设有同步锁,⾼并发时出现锁等待;
调优⽅案:
SQL问题:没有索引就创建索引,SQL语句筛选条件不明确就优化SQL和业务逻辑;
同步锁问题:是否去掉同步锁,有时候不仅仅是技术问题,还涉及到业务逻辑的各种判断,是否去掉同步锁,建议和开发产品同事沟通确认;
5、压测过程中TPS不断下降,CPU使⽤率不断降低
原因解析:⼀般来说,出现这种问题的原因是因为线程block导致,当然不排除其他可能;
调优⽅案:如果是线程阻塞问题,修改线程策略,然后重新验证即可;
6、其他
除了上述的五种常见性能瓶颈,还有其他,⽐如:connection reset、服务重启、timeout等,当然,分析定位后,你会发现,我们常见的性能瓶颈,
导致其的原因⼤多都是因为参数配置、服务策略、阻塞及各种锁导致。。。
性能瓶颈分析参考准则:从上⾄下、从局部到整体!
以上分析及调优⽅案仅供参考,具体定位还需要根据⽇志监控等⼿段来分析调优。。。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论