看完这篇入门性能测试

news2024/12/26 10:40:46

大家好,我是洋子。最近组内在进行服务端高并发接口的性能压测工作,起因是2023年2月2日,针对胡某宇事件进行新闻发布会直播,几十万人同时进入某媒体直播间,造成流量激增

从监控上可以看出,QPS到达某峰值后,部分进入直播间即调用的接口(这类接口属于高并发接口,在短时间内承载非常高的QPS)以及对应接口的下游,均出现了非常严重的服务可用性下降,部分接口可用性下降到了60%,并且 接口平均响应时间从500ms(毫秒)飙升到 6 s

经过分析,得出可用性下降以及接口平均响应时间飙升的原因为数据库服务挂掉

出现线上数据库服务挂掉这样的异常事件,可以看出我们对整个直播系统的架构并没有认识到性能瓶颈,主要的盲点如下:

  • 一个微服务当中的高并发接口究竟能抗多大的QPS
  • 当超过性能极限的QPS后,是否有限流/降级/熔断的策略在执行,或者直接对功能进行云控开关限制
  • 流量高峰期当中,系统是否能正常提供服务,是否有隐藏问题

解决这些盲点的方法就是进行容量压测,本篇文章我将带大家体验容量压测的全流程,本文主要内容为:

  • 什么是容量压测
  • 容量压测的全流程(前期准备,发压执行)
  • 压测结果和性能调优

什么是容量压测

容量压测(Capacity Testing) 是一种软件性能测试方法,主要用于评估系统在特定负载下的容量。其目的是确定系统可以处理的最大工作负载,以及在达到容量极限时,系统是否能够保持其性能和稳定性

容量压测和一般接口压测的区别

容量压测和一般的接口压测都会模拟实际生产环境下的负载情况,通过不断增加并发用户数来逐渐加大负载,两者的区别在于容量压测需要压到系统开始出现性能问题或崩溃,而一般的接口压测只需要满足在性能测试方案当中指定的并发用户数即可,不需要压到服务有损

压测常用的性能指标概念介绍

在容量压测试过程中需要监控系统的各项性能指标,如响应时间、吞吐量(QPS)、资源使用率(CPU、内存和网络)、服务可用性、错误码等,并记录压测结果

QPS

QPS(Queries Per Second):表示每秒查询率,用来衡量系统每秒能够处理的请求数量

日常接口压测中,通过制定压测方案,先确定要压到的QPS数量,压测执行完毕后若没有性能问题,则表明该接口能扛住对应的QPS,用来衡量对应系统的吞吐量好坏

TPS

TPS(Transactions Per Second):表示每秒事务处理量,即系统每秒能够处理的事务数量。一个事务可能包含多个请求,因此完成一个事务所需的时间往往比处理一个请求的时间更长,这就导致了 TPS 通常比 QPS 更低

系统的复杂性和实现方式不同,可能会影响到每个事务或查询的处理时间,实际情况下大多数场景QPS和TPS两者近似相等

响应时间

响应时间是指从客户端发一个请求开始计时,到客户端接收到从服务器端返回的响应结果结束所经历的时间

响应时间由请求发送时间、网络传输时间和服务器处理时间三部分组成,一般取平均响应时间

计算方式:响应时间=发送时间(约等于0)+网络传输时间(N1+N2+N3+N4)+服务器处理时间(A1+A2+A3)
在这里插入图片描述
响应时间一般会随着并发用户数(负载)上升不断升高

并发用户数

并发用户数:系统同时存在处理的请求数量,并发用户数常简称为并发数

并发用户数是衡量系统负载的关键指标,并发用户数越多,系统的负载就越高

负载(用户负载)指的是当前正在访问或使用某个系统、应用程序或服务的并发用户数。当提到负载或用户负载,可以代指并发用户数

  • 计算方式:并发用户数=QPS*平均响应时间 (论证计算方式见下方吞吐量介绍)

吞吐量

吞吐量指的是单位时间内系统处理的请求数量,系统吞吐量由QPS(TPS)并发用户数平均响应时间共同决定
在这里插入图片描述
多数情况下QPS和TPS近似相等,而QPS由并发用户数和平均响应时间决定

所以对于服务端来说,系统吞吐量一般直接用QPS来作为量化指标,换句话说别人问起某系统的吞吐量有多高,就是指这个系统能抗的QPS有多大

  • 计算单位:请求数/秒(最常用) ,页面数/秒,访问人数/天,页面访问量/天
  • 计算方法:吞吐量=请求总数/总时间=并发用户数/平均响应时间=QPS

利用计算并发用户数的经验公式来验证QPS的计算方法的正确性

在这里插入图片描述
通过查看上图论证过程,可以得知计算 并发用户数,计算QPS的正确性

资源利用率

不同系统资源的使用程度,通常用占用最大值的百分比或均值的百分比来衡量,通常需要关注的资源有CPU,内存,磁盘,线程数

压测中需要关注Web服务实例,数据库实例,缓存实例的资源利用率,CPU利用率是重点指标

服务可用性

服务可用性为异常请求数量占请求总数的占比,在性能测试中,根据实际情况,需要关注对应压测服务接口以及接口下游服务的可用性,数据库服务,缓存服务可用性等

计算方式:服务可用性 = 100 - 请求异常数量 / 请求总数 * 100

实际例子计算并发用户数

看完这些概念,是不是还是感觉一脸懵逼,用一个实际的场景来1秒内并发地来了160个请求,那么此时QPS和并发用户数都怎么计算呢

从上面计算公式可以得知,QPS为160,但无法计算并发数,前面我们知道了,并发数=QPS平均响应时间。但这里缺少了响应时间,假设响应时间为100 ms(0.1s),并发用户数为1600.1=16

系统同时(1s内)在处理16个用户的请求,这就是系统支持的并发用户数
在这里插入图片描述

性能指标之间的联系

并发用户数资源利用率/吞吐量/响应时间这3个指标之间关系密切。随着并发用户数增大,资源利用率,吞吐量,响应时间都会发生不同的变化

引用一张非常经典的性能指标图片来说明它们之间的关系,该图来自2005 年 Quest Software 的白皮书《Performance Testing Methodology》
请添加图片描述
在这个图中,横坐标为并发用户数(衡量系统负载的重要指标),纵坐标有3层含义:分别是资源利用率(CPU/内存,下面统称为CPU),吞吐量(对于衡量服务端吞吐量,一般用QPS代替,下面统称为QPS),响应时间

通过此图,可以看到三条曲线、三个区域、两个点以及三个状态描述

三条曲线:QPS(紫色)、CPU(绿色)、响应时间(深蓝色)
三个区域:轻负载区(Light Load)、重负载区(Heavy Load)、塌陷区(Buckle Zone)
两个点:A点为最优并发用户数(The Optimum Number of Concurrent Users)、B点为最大并发用户数(The Maximum Number of Concurrent Users)
三个状态描述:资源饱和(Resource Saturated)、吞吐下降(Throughput Falling)、用户受影响(End Users Effected)

用大白话解读一下这张图

假设刚开始系统只有一个用户,CPU工作处于不饱合状态。一方面该服务器可能有多个CPU,但是只处理单个进程;另一方面,在处理一个进程中,可能IO等待阶段,因为没有其他用户,所以没有其他请求进程可以被处理,这个时候会造成CPU等待

随着并发用户数的增加(未超过A点),CPU利用率逐步上升,平均响应时间也在增加,QPS相应也增加

而当并发数增加到很大时(超过B点),每秒钟都会有很多请求需要处理,会造成进程(线程)频繁切换,真正用于处理请求的时间变少,每秒能够处理完的请求数反而变少(即QPS开始下降),但用户的请求等待时间(响应时间)也会持续变大,最后超过用户的心理底线

综上所述

在最小并发数和最大并发数之间,一定有一个最合适的并发数值,在最佳并发 数下,QPS能够达到最大。但是,这个并发并非是一个最佳的并发,因为当QPS到达最大时的并发,可能已经造成用户的等待时间变得超过了其最优值

对于一个系统来说,最佳的并发数需要结合QPS以及用户的等待时间来综合确定

有小伙伴就有疑问了,QPS怎么还会下降呢,从数学的角度来解释一下原理,见下图

表示并发用户数和响应时间关系的深蓝色曲线,以B点为分界点,在横坐标[1,B]以及[B,正无穷]区间内,增长速率有所不同

当并发用户数没有到达点B时,曲线的斜率小于1,所以在初期由于并发用户数的增速比平均响应时间更快,分子比分母涨得快,所以QPS不断上升
在这里插入图片描述

并发用户数超过点B后,曲线呈现出指数增长,并发用户数和响应时间的曲线的斜率大于1,并发用户数的增速比平均响应时间还慢,分母比分子涨得快,所以QPS下降
在这里插入图片描述
从QPS的计算公式可以得出,QPS是由并发用户数,平均响应时间两者共同决定

谈到QPS时,一定需要指明是多少并发用户数下的QPS,否则毫无意义,因为单用户的40QPS和 20个 并发用户下的40QPS是两个不同的概念(单机压测和分布式压测效果会有区别)

前者说明该应用可以在一秒内串行执行40个请求,而后者说明在并发20个请求的情况下,一秒内该应用能处理 40 个请求,当QPS相同时,越大的并发用户数,代表了服务的并发处理能力越好

容量压测的全流程

容量压测也是属于性能测试,和一般的性能测试流程相同,需要值得注意的是,如果是使用线下环境压测,压测流程如下
在这里插入图片描述
而对于直接使用线上环境(生产环境)压测,则无需进行流量构造,压测环境部署,预热这3个环节
在这里插入图片描述

场景设计

在进行性能测试之前,第一步是进行压测的场景设计,是指针对单接口还是多个接口有关联,需要组合起来同时压测

由于本次容量压测只针对高并发的单接口,通过查看监控平台某时间段的接口请求流量情况,以及查看代码得知代码架构和调用时机,我就确定好了高并发接口的范围,并没有花时间在场景设计上

高并发是指在同一时间内,系统或应用程序所处理的并发请求量非常高。在一个系统或应用程序中,如果同时有大量的用户或进程访问同一个资源或进行相同的操作,就会出现高并发的情况。这种情况下,系统或应用程序需要同时处理大量的请求,如果处理不当,可能会导致系统响应变慢、延迟或崩溃等问题

高并发处理能力是一个系统或应用程序的重要指标之一。为了提高高并发处理能力,通常需要采用分布式、缓存、负载均衡、异步处理等技术来优化系统的性能

数据构造

在本次压测的接口当中,有部分接口的参数需要动态获取,不能写死,否则会命中缓存,起不到压测的效果。如下方接口参数,param2参数的值,为从文件当中读取一批提前生成好的数据。平时在进行压测时,通常我们可以通过用Python写一些造数脚本,满足性能测试数据构造的需求

另外接口信息,如URL和请求参数也需要提前配置好,发压工具可以使用JmeterLoucstLoadrunner

{"param1": 123456,
"param2":${id},
"param3":10000006,
"param4":"6.7.5"
}

流量构造

压测前若使用线下环境压测需要提前进行流量构造,对于流量的构造也有下面几种不同的策略

  • 拷贝和线上流量完全相同的流量到线下
  • 对线上流量进行染色
  • 使用线上流量+构造部分线下流量
  • 完成构造线下流量

压测环境部署

为了避免对生产环境影响,也可以使用线下环境进行压测,如果使用线下环境,需要提前部署好压测环境

预热

对于线下环境,部署好压测环境,一般不能马上进行压测,需要进行预热,也就是等机器空跑5-10分钟,这是因为在环境刚启动的时候,系统的响应时间,CPU,内存环境刚启动的时候均处于不稳定的状态

执行压测&实时监控

前面的准备工作都做完成了,就可以开始压测,在进行压测过程中,注意通知开发一起关注监控。常见的监控指标:机器内存使用率(机器包括部署程序实例,数据库服务,缓存服务)、CPU利用率和代理层服务以及下游可用性,响应时间,错误码等

结果分析和调优

性能测试后,发现的问题多种多样,我总结了一些常见的调优方法

  • 增加限流/熔断/降级策略
  • 增加功能限制开关:在达到某一QPS峰值后,利用云控开关关闭此功能,从而阻止流量激增对后端服务带来的影响
  • 增加服务器资源:如果应用程序的性能瓶颈是由于服务器资源不足导致的,可以考虑增加服务器资源。例如,增加CPU、内存或网络带宽等
  • 优化数据库查询:如果应用程序的性能瓶颈是由于数据库查询效率低下导致的,可以考虑优化数据库查询。例如,使用索引、减少查询结果集、缓存查询结果等
  • 优化代码:如果应用程序的性能瓶颈是由于代码效率低下导致的,可以考虑优化代码。例如,使用更有效的算法、避免重复计算、减少数据库操作等
  • 缓存:如果应用程序的性能瓶颈是由于频繁的数据访问导致的,可以考虑使用缓存。例如,客户端可使用本地缓存、后端使用Redis缓存等。
  • 负载均衡:如果应用程序的性能瓶颈是由于流量集中在某个服务器上导致的,可以考虑使用负载均衡。例如,使用Nginx、HAProxy等工具进行负载均衡

以上是一些常见的性能调优案例,具体情况需要根据应用程序的特点和性能瓶颈来确定。同时,在执行性能调优时,需要谨慎考虑对应用程序的影响,并进行充分测试,以确保解决方案是可行和有效的

结束语

在本次压测当中,也出现了很有意思的问题,在这里分享一下

(1)简单SQL竟然出现了慢查询:根本原因是同一行SQL并发写操作执行命中锁,导致阻塞
(2)数据库链接超时:排查后竟然不是数据库服务本身的问题,根本原因是部署服务机器实例CPU利用率飙升,导致无法及时处理数据库链接

压力测试在越发复杂的大型互联网系统架构下,起到至关重要的作用,希望本篇文章对你有所收获

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/389895.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

brew安装问题

最近使用mac安装了Python和PyCharm,使用python中的绘制图像的turtle库后,执行报错: import _tkinter # If this fails your Python may not be configured for Tk ModuleNotFoundError: No module named _tkinter 查询后需在mac 命令行执行&…

【网络监控】Zabbix详细安装部署(最全)

文章目录Zabbix详细安装部署环境准备安装依赖组件访问初始化配置Zabbix详细安装部署 Zabbix 是一个高度集成的网络监控解决方案,可以提供企业级的开源分布式监控解决方案,由一个国外的团队持续维护更新,软件可以自由下载使用,运作…

【前端必看】极大提高开发效率的网页 JS 调试技巧

大家好,我是前端西瓜哥。本文讲解如何使用浏览器提供的工具进行 JS 代码的断点调试。 debugger 在代码中需要打断点的地方,加上 debugger,表示一个断点。浏览器代码执行到该位置时,会停下来,进入调试模式。 示例代码…

java内存模型的理解

java内存模型的理解并发问题产生的源头缓存导致的可见性问题线程切换导致的原子性问题编译优化带来的有序性问题小结Java内存模型: 解决可见性和有序性问题Java内存模型与JVM内存模型的区别volatile关键字Happens-Before规则小结思考题参考并发问题产生的源头 缓存导致的可见性…

【Verilog】——Verilog简介

目录 1.简介 2.什么是HDL以及HDL的功能 3.Verilog和C语言的比较 4.Verilog的用途 5.数字系统的抽象层次 1.系统级 2.算法级 3.RTL级(寄存器变换级) 6.数字系统抽象层级 7.自顶向下的结构化设计方法 8.Verilog建模 9.Verilog概述 10.Verilog模块的基本…

Django学习17 -- ManytoManyField

1. ManyToManyField (参考:Django Documentation Release 4.1.4) 类定义 class ManyToManyField(to, **options)使用说明 A many-to-many relationship. Requires a positional argument: the class to which the model is related, which w…

推导部分和——带权并查集

题解: 带权并查集 引言: 带权并查集是一种进阶的并查集,通常,结点i的权值等于结点i到根节点的距离,对于带权并查集,有两种操作需要掌握——Merge与Find,涉及到路径压缩与维护权值等技巧。 带…

用Python批量重命名文件

案例 今天,我们来整理文件夹中的文件,给某个文件夹下的所有文件重新命名。要求是给所有文件按照修改时间,按顺序在文件名前面加上编号。比如将文件资料.xlsx重命名为1. 资料.xlsx import osdef Get_modify_time(file):return os.path.getmtime(file) #获取文件修改时间path…

vue3的v-model指令

1. 普通input输入框双向绑定 <template><!-- 1. 普通input输入框双向绑定 --><!-- 其实等价于&#xff1a;<input :modelValue"title" update:modelValue"newTitle>titlenewTitle"/> --><input type"text" v-mod…

Junit测试框架

一、简介 Junit框架是一个开源的Java语言单元测试框架&#xff0c;Java方向使用最广泛的单元测试框架&#xff0c;使用Java开发者都应该学习Junit并能掌握单元测试的编写。 对于Junit和Selenium的关系&#xff1a;通俗点来说Selenium如果比喻为灯泡&#xff0c;那么Junit就是电…

【蓝桥杯集训15】求最短路存在负权边——spaf算法(2 / 4)

——SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称 单源最短路&#xff0c;且图中没有负环就可以用spfa 目录 spaf求最短路模板 852. spfa判断负环 341. 最优贸易 - 3305. 作物杂交 - spaf求最短路模板 只有当一个点的前驱结点更新了&#xff0c;该节点才会得到…

操作系统——16.时间片轮转、优先级、多级反馈队列算法

这篇文章我们来看一下进程调度算法中的时间片轮转、优先级、多级反馈队列算法 目录 1.概述 2.时间片轮转调度算法&#xff08;RR&#xff0c;Round-Robin&#xff09; 3.优先级调度算法 4.多级反馈队列调度算法 5.分析对比 1.概述 首先&#xff0c;我们来看一下这篇文章…

计算机网络整理

TCP与UDP 介绍 HTTP&#xff1a;&#xff08;HyperText Transport Protocol&#xff09;是超文本传输协议的缩写&#xff0c;它用于传送WWW方式的数据&#xff0c;关于HTTP协议的详细内容请参考RFC2616。HTTP协议采用了请求/响应模型。 TCP:&#xff08;Transmission Contro…

[YOLO] yolov3、yolov4、yolov5改进

yolov3网络结构图&#xff1a; Yolov3的三个基本组件&#xff1a; &#xff08;1&#xff09;CBL&#xff1a;Yolov3网络结构中的最小组件&#xff0c;由ConvBnLeaky_relu激活函数三者组成。 &#xff08;2&#xff09;Res unit&#xff1a;借鉴Resnet网络中的残差结构&#x…

docker 入门篇

docker为什么会出现&#xff1f; 一款产品&#xff1a;开发---->运维&#xff0c;两套环境&#xff01;应用环境&#xff0c;应用配置&#xff01; 常见问题&#xff1a;我的电脑可以运行&#xff0c;版本更新&#xff0c;导致服务不可用。 环境配置十分的麻烦&#xff0c;…

RL笔记:基于策略迭代求CliffWaking-v0最优解(python实现)

目录 1. 概要 2. 实现 3. 运行结果 1. 概要 CliffWalking-v0是gym库中的一个例子[1]&#xff0c;是从Sutton-RLbook-2020的Example6.6改编而来。不过本文不是关于gym中的CliffWalking-v0如何玩的&#xff0c;而是关于基于策略迭代求该问题最优解的实现例。 CliffWalking-v0的…

Promise-异步回调

1.理解Promise promise是ES6提出的异步编程的新的解决方案&#xff0c;通过链式调用解决ajax回调地狱 从语法上看&#xff0c;promise是一个构造函数&#xff0c;自己身上有all、reject、resolve方法&#xff0c;原型上有then、catch方法 从功能上看&#xff0c;Promise对象用…

BloomFilter原理学习

文章目录BloomFilter简单介绍BloomFilter中的数学知识fpp(误判率/假阳性)的计算k的最小值公式总结编程语言实现golang的实现[已知n, p求m和k](https://github.com/bits-and-blooms/bloom/blob/master/bloom.go#L133)参考BloomFilter简单介绍 BloomFilter我们可能经常听到也在使…

瑞吉外卖——day2

目录 一、新增员工 二、查询分页数据 三、启用、禁用员工账户、编辑员工信息 一、新增员工 点击左上角新增员工 页面如下&#xff1a; 我们随便填数据 &#xff0c;点击保存&#xff0c;请求的地址如下 返回前端可以看到请求方式为Post 在employeeController中编写对应的代…

Elasticsearch:图片相似度搜索的 5 个技术组成部分

作者&#xff1a;Radovan Ondas&#xff0c;Bernhard Suhm 在本系列博文的第一部分中&#xff0c;我们介绍了图像相似度搜索&#xff0c;并回顾了一种可以降低复杂性并便于实施的高级架构。 此博客解释了实现图像相似性搜索应用程序所需的每个组件的基本概念和技术注意事项。 学…