完成工具使用和脚本编写后,剩下的流程是执行和结果分析,以及复测。现在来学学结果分析,主要是要学会判断压力的来源,当响应时间远远超出我们的期望,测试人员如何判断是由于什么导致的过载响应。
一、性能瓶颈出现的表现
1.1 性能瓶颈出现频次具体表现
1.1.1 CPU占用高
常见原因:1、代码逻辑错误, sql被错误执行,
2、执行时进行大量扫描操作(未命中索引)【type为all时表示全表扫描, 一般存在问题】
调优方案:1、修改代码逻辑,优化sql查询方式,使用索引进行查询
1.1.2 高高并发下大量报错
常见原因:1、线程池最大线程数配置较小
2、接口请求超时间较短,
3、有短连接导致的端口被完全占用
调优方案:1、修改服务节点的tcp_tw_reuse参数为1,释放TIME_WAIT scoket用于新的连接
2、 修改超时时间,参考jmeter超时时间配置方案
3、修改服务节点中容器的server.xml文件中的配置参数,主要修改如下几个参数:
# 最大线程数,即服务端可以同时响应处理的最大请求数
maxThreads="200"
# Tomcat的最大连接线程数,即超过设定的阈值,Tomcat会关闭不再需要的socket线程
maxSpareThreads="200"
# 所有可用线程耗尽时,可放在请求等待队列中的请求数,超过该阈值的请求将不予处理,返回Connection refused错误
acceptCount="200"
1.1.3 中集群类系统,各服务节点负载不均衡
常见原因:1、出现这类问题的原因一般是SLB服务设置了会话保持,会导致请求只分发到其中一个节点
调优方案:1、可通过修改SLB服务(F5/HA/Nginx)的会话保持参数为None,然后再次压测验证
1.1.4 中并发数不断增加,TPS上不去,CPU耗用不高
常见原因:1、SQL没有创建索引/SQL语句筛选条件不明确
2、代码中设有同步锁
3、高并发时出现锁等待
调优方案:1、创建索引
2、去掉同步锁,涉及到业务逻辑,需要和开发以及产品业务沟通确定【同步锁主要是:保护数据完全性。当多个用户同时访问一个数据库时,就会面临数据的完全性问题,为了不这类情况,SQL Server提供了一个同步锁(lock)机制】
3、当在操作mysql数据库的表数据时,发现更新某表的xx字段时,系统老是提示“Lock wait timeout exceeded; try restarting transaction”错误。一般情况下,出现这个情况的原因可能是当一个sql执行完之后,但是该事务处于未commit的状态,后面的sql语句如果也对该字段进行操作,就会出现锁等待的情况,优化方向可以按照如下考虑:
A:优化SQL语句,在编写SQL语句时,应该尽可能地避免使用全表扫描、多表连接等操作,这些操作容易导致锁等待的问题;
B:减少事务量,事务是锁等待的主要来源之一,因此可以通过减少事务量来减少锁等待的概率。可以将多个小事务合并成一个大事务,或者通过修改业务逻辑来减少事务量;
C:提高硬件性能
1.1.5 低压测过程中TPS不断下降,CPU使用率不断降低
二、常见的负载因素识别
1、数据库的性能瓶颈
数据库索引,锁,表空间,慢sql,数据量
1.1 缺乏索引:
1.2 查询效率低:
1.3 数据类型不正确:
1.4 连接数不够
1.5、缓存命中率低
2、应用程序的性能瓶颈
程序架构规划不合理,程序本身设计有问题(串行处理、请求的处理线程不够),造成系统在大量用户方位时性能低下而造成的瓶颈。
3、网络的性能瓶颈
网络带宽(每秒多少bit)
网络抖动=最大延迟-最小延迟,——差值越小,网络越稳定
时延
丢包
4、硬件的性能瓶颈
4.1 CPU:CPU的晶体管数量和频率,单核叫多核cpu性能较差
行业cpu指标,高于如下数据,可以定位为性能瓶颈【使用top或vmstat命令查询】:
a) User Time:65%~70% (表示程序本身以及它所调用的库中的子例程使用的时间)
b) System Time:30%~35% (由程序直接或间接调用的系统调用执行的时间)
c) Idle:0%~5% (空闲时间占比,cpu使用率,越大表示cpu使用率越高,0表示空闲状态)
指标数据详细解读:
1)、User Time+System Time<70% 系统良好
2)、70%<User Time+System Time<90% 系统有些压力
3)、User Time+System Time>90% 系统负荷很重,cpu资源短缺
4)、Idle<10% CPU处理能力相对较低,表明系统中最需要改善的资源是CPU
5)、若Idle=0%且System Time%>2User Time%,责CPU资源短缺
4.2 内存:系统内存【可用内存,剩余内存,已用内存,缺页异常,缓存/缓冲区】,进程内存,swap
性能指标分析:
1)、交换空间的si和so持续地大于0,可能存在内存的瓶颈,有大量数据在物理内存和磁盘交换空间进行换入换出,此时应加大物理内存容量
2)、Idle%的值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大物理内存容量
3)、若内存的占用率比较高,但CPU的占用很低时,可以考虑是有很多的应用程序占用率内存没有释放
性能工具以及与性能指标的联系:
free:查看系统整体内存和 Swap的使用情况。
top 或 ps:查看进程的内存使用情况。
vmstat:动态观察内存变化情况,区分了缓存和缓冲区、Swap的换入换出的内存大小。
cachestat:查看整个系统缓存的读写命中情况。
cachetop:查看进程缓存的读写命中情况。
memleak:给出内存分配栈,找出内存泄漏的可能位置。
sar:内存和 Swap的使用情况
内存性能瓶颈分析过程流程图
优化思路:
1、最好禁止Swap,如果实在需要开启,就调低 swappiness 的值,减少内存回收时Swap使用倾向。
2、减少内存的动态分配,可以使用内存池或者大页(HugePage)等。
3、尽量使用缓存 / 缓冲区访问数据。比如,可使用堆栈明确声明内存空间,来存储需要缓存的数据;或者用Redis这类外部缓存组件,优化数据访问。
4、使用 cgroup等方式限制进程的内存使用情况,可确保系统内存不会被异常进程耗尽。
5、通过 /proc/pid/oom_adj,调整核心应用的 oom_score ,可保证即使出现内存紧张的情况,核心应用也不会被OOM机制杀死。
4.3 I/O读写速率:
1)、avgqu-sz的值较低,设备的利用率较高
2)、当%iowait的值大于40%,表示磁盘存在严重地I/O瓶颈
3)、当%util的值接近100%时,表示设备带宽已经占满
5、中间件的性能瓶颈
超时设置,线程池设置,缓存策略,最大连接数,负载均衡策略、消息队列
5.1 关于中间件在性能主要有几个小问题:
1、如何判断性能问题是出自应用中间件?——响应时间
如果这个值出现异常,那就说明业务在中间件中的这段处理可能有问题,这段时间包括了收到请求到分配执行的时间,包括了应用等待数据库连接池的时间、包括中间件调用数据库执行时间等等,然后我们再分段分析哪里出现了问题。如果ResponseTime较长,而从数据库上查看SQL的执行时间很短,那么8成就是中间件里面的时间长了
2、中间件参数有千千万,着重查看应用中间件的哪些重要指标?
1)ServiceTime:完成servlet请求的平均响应时间(毫秒)
2)ResponseTime:接收到请求和方茴应答之间的平均时间
3)RequestResponseTime:接到请求与分派执行之间的时间
4)DispatchResponseTime:从分派执行到返回应答之间的平均时间。
3、采用什么工具来监控中间件?
4、中间件如何影响系统的性能指标(如吞吐量、响应时间、交易成功率)?
5、如何优化应用中间件的参数以期提高系统的性能?
超时设置:
线程池:
缓存策略【Redis】
应用概念:redis是这样被使用的:系统的业务数据仍然存在mysql数据库中,每当一个新用户登录系统进行查分时,会将数据从mysql数据库中取出并存入redis中,当这个用户第二次在进行查分时,会直接从redis中取数据,而不会在去查mysql数据库。因为数据已经被缓存至redis库中,从redis中读取直接走内存,比mysql更快,可以避免大量查询会导致mysql数据库出现异常
性能问题:缓存命中率低【原因:读取的数据在缓存中不存在】
解决方案:1、提高缓存过期时间;2、提升缓存容量;3、更改缓存策略
性能问题:缓存并发问题【原因:多个客户端对Redis缓存进行读写操作。出现的缓存丢失和缓存竞争问题】
解决方案:1、使用Redis事物【避免多端单位出现的竞争问题】;2、使用Redis琐【保证只能有一个进行读写操作】
性能问题:网络延迟问题【原因:网络延迟导致Redis和客户端之间的延迟】
解决方案:1、将Redis服务器放置在同一局域网内【避免跨网传输数据带来的延迟问题】;2、使用Redis集群【分布式缓存系统,可以实现数据的高可用性和负载均衡】
性能问题:缓存穿透
1、Redis含义: Redis是一个高性能的键值对存储数据库,也是一个基于内存的数据结构存储系统,同时也支持持久化数据存储。Redis提供了丰富的数据结构,包括字符串、哈希、列表、集合、有序集合等。在缓存方面,Redis最大的优点就是支持数据的持久化存储,同时也具有很好的性能和扩展性。
2、性能分析1)缓存穿透含义: 缓存穿透,是指查询一个数据库一定不存在的数据,请求会直接穿透到数据库
2)性能问题:由于查询不到数据而直接对数据库发起的大量请求导致数据库压力倍增
3)正常数据请求处理流程:正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。
4)解决思路:1、空对象缓存【含义:当查询的数据不存在时,将一个空对象缓存到Redis中。这样下次查询同样不存在的数据时,就可以直接从Redis中获取到一个空对象,从而避免了对数据库的查询操作,同时设置缓存过期时间5分钟,这样即使缓存中的数据被清空了,也不会引起数据库的压力过大,从而避免了缓存穿透】;2、布隆过滤器【含义:查询的数据在位图中不存在,那么直接返回不存在】
负载均衡策略:
消息队列:
1、常用消息中间件
RabbitMQ、RocketMQ、Kafka(分布式流处理平台)、Pulsar(分布式消息流平台)
2、