大家好,我是黎潘,来自重庆,狂师老师的全栈测开训练营中上一期的学员。
大多数测试人员在谈到性能测试时,往往会倍感压力。对于我来说更是如此,想做好性能测试需要庞大的知识体系
,不断实践所总结的经验教训更是弥足珍贵。而且每个人对性能测试的理解都有独到的地方,此次有幸参加全栈测开训练营在狂师老师的指导下逐步揭开性能测试得神秘面纱,结合课堂学习及自身消化理解后的,归纳了一些性能测试的基础知识,希望对大家理解性能测试有所帮助。
一、简述性能测试
性能测试含义:系统在一个给定的环境和场景中的性能表现是否与预期目标一致,评判系统是否存在性能缺陷,并根据测试结果识别性能瓶颈,改善系统性能的完整的过程。
介入时机:通常是在功能测试完成之后,并且系统功能处于相对稳定状态。
1.1 性能测试开展范围
客户端:web端,PC端,移动端,小程序,每一个都是不同领域的性能测试,关注点都不尽相同。还包括一个服务端的性能测试,本篇也主要是以服务端的性能测试来展开的。
1.2 软件性能关注点
- 终端用户
使用过程中更加关注响应时间,稳定性。总得来说就是用户体验要好。
- 系统运维人员
系统最大并发,最大业务处理量,能支持多少用户访问,能否长时间提供服务,服务器资源使用,数据库资源使用,系统是否可以实现扩展。总的来说,更加关注系统的稳定性,资源利用率,可扩展性,系统容量等。
- 软件设计开发人员
架构设计,数据库设计,代码设计,是否存在不合理的内存使用和线程同步方式,以及资源竞争等,总的来说,更加关注系统架构,数据库设计,设计与代码实现等。
- 性能测试人员
系统资源指标,业务性能指标,DB性能指标,系统稳定性,支持最大并发,性能拐点等,几乎包括了上述所有人员的关注点。
二、后端性能常见指标
2.1 业务性能指标
并发用户数:并发用户数取决于业务并发用户数和用户行为模式,也就是说实际使用的用户并不是每种用户行为都会对服务端产生压力,通常是指同一批用户同时执行一个对后端服务产生压力的操作行为。
响应时间:响应时间是系统最重要的性能指标,直观的反映了系统的快慢。指的是用户端发出请求到得到响应的整个过程所经历的。
系统处理能力:系统处理能力是指系统在利用系统硬件平台和软件平台进行信息处理的能力,通常有以下几个指标衡量。
- TPS:每秒事务数,指服务器在单位时间内(秒)可以处理的事务数量。
- QPS:每秒查询率,指服务器在单位时间内(秒)处理的查询请求速率。
- HPS:每秒点击次数,单位是次/秒。
吞吐量:系统在单位时间内处理请求的数量。
事务成功率:单位时间内系统可以成功完成多少个定义的事务。
超时错误率:主要指事务由于超时或系统内部其它错误导致失败占总事务的比率。
2.2 系统资源指标
CPU使用率:指用户进程与系统进程消耗的CPU时间百分比。
内存利用率:内存利用率=(1-空闲内存/总内存大小)*100%。
磁盘I/O:磁盘吞吐量简称为 Disk Throughput,是指在无磁盘故障的情况下单位时间内通过磁盘的数据量。
网络带宽:发送和接收字节的速率,包括帧字符在内。
数据库性能指标:sql语句,连接数,读写速度,资源使用率等。
上述只是一些常见的指标,通常还包括一些其他中间件,以及整个链路所经过的服务器指标。
2.3 并发用户数,响应时间,系统吞吐量三者之间的关系
未达到系统瓶颈:随着并发用户数的增加,系统吞吐量会逐渐增加,此时响应时间会较快。
达到系统瓶颈:随着并发用户数的增加,系统吞吐量不再会增加,此时响应时间会开始变长。
超过系统瓶颈:随着并发用户数的增加,系统吞吐量出现下降,此时响应时间会逐渐拉长,甚至无响应。
三、常见性能测试方法
后端性能测试:通过模拟一定的并发用户量,获取一系列需要的系统,业务性能指标,来验证是否满足我们预期性能需求或者探索系统的容量和潜在的问题。
代码级性能测试:在单元测试阶段,针对代码本身,例如通过多次执行单元测试用例,获取一些关键算法的性能指标,是否满足需求。
压力测试:系统在一定资源饱和的情况下,模拟一定用户量,不断对系统施压,验证系统处于压力情况下的性能表现,寻找系统的性能瓶颈点。
配置测试:观察系统在不同配置下性能的表现,了解不同环境配置对系统性能的影响程度。
并发测试:模拟多个用户同一时间访问一个系统,模块或数据记录等其他并发操作,关注系统可能存在的性能瓶颈,如内存泄漏,线程死锁或资源竞争等问题。
可靠性测试:给系统施加一定的压力,持续运行一段时间,观察系统能否稳定运行。
四、企业中常见性能测试类型
性能基准测试:基于固定的硬件环境和部署架构(比如专用的服务器、固定的专用网络环境、固定大小的集群规模、相同的系统配置、相同的数据库背景数据等),通过执行固定的性能测试场景得到系统的性能测试报告,然后与上一版本发布时的指标进行对比,如果发现指标有“恶化”的趋势,就需要进一步排查。
稳定性测试:又称可靠性测试,主要是通过长时间(7*24 小时)模拟被测系统的测试负载,来观察系统在长期运行过程中是否有潜在的问题。通过对系统指标的监控,稳定性测试可以发现诸如内存泄漏、资源非法占用等问题。
并发测试:是在高并发情况下验证单一业务功能的正确性以及性能的测试手段。高并发测试一般使用思考时间为零的虚拟用户脚本来发起具有“集合点”的测试。
容量规划测试:是为了完成容量规划而设计执行的测试。容量规划的主要目的是,解决当系统负载将要达到极限处理能力时,我们应该如何通过垂直扩展(增加单机的硬件资源)和水平扩展(增加集群中的机器数量)增加系统整体的负载处理能力的问题。
五、常见的性能测试工具
目前市面上比较常见的服务端性能测试少说也有几十种,这里我们简单的比较下常见的三种,即JMeter,locust,LoadRunner。
5.1 组件对比
5.2 功能区别
通过以上对比,大家结合自己公司的需求,选择合适的性能测试工具。
5.3 locust入门
定义
Locust是使用Python语言编写实现的开源性能测试工具,简洁、轻量、高效,并发机制基于gevent协程,可以实现单机模拟生成较高的并发压力。中文意为:蝗虫,蝗虫过境,寸草不生。
主要特点
- 使用Python语言编写用户测试场景
- 分布式、可扩展,支持成千上万的用户
- 基于事件驱动,基于gevent协程实现并发机制。
- 基于Web的用户界面,用户可以实时监控脚本运行状态
- 几乎可以测试任何系统,除了Web HTTP接口外,还可自定义Clients测试其他类型系统
安装
直接通过pip install locust
命令安装。
安装成功后可以输入pip show locust
命令查看是否安装成功,以及通过locust --help
查看帮助信息。
简单脚本示例
代码语言:javascript复制from locust import HttpUser, TaskSet, task
class WebsiteTasks(TaskSet):
# 任务启动前置执行
#def on_start(self):
self.login()
# self.client属性使用Python request库的所有方法,调用和使用方法和requests完全一致
#def login(self):
# self.client.post("/login", {"username": "mikezhou", "password": "123456"})
# 此脚本用不到提前登陆,只起个示例作用,运行前注释掉
@task(2) # 通过@task()装饰的方法为一个事务,方法的参数用于指定该行为的执行权重,参数越大每次被虚拟用户执行的概率越高,默认为1
def index(self):
self.client.get("/")
def about(self):
self.client.get("/about/")
class WebsiteUser(HttpUser):
# 被测系统的host,在终端中启动locust时没有指定--host参数时才会用到
host = "http://example.com"
# TaskSet类,该类定义用户任务信息,必填。这里就是WebsiteTasks类名,因为该类继承TaskSet
tasks = [WebsiteTasks]
# 每个用户执行两个任务间隔时间的上下限(毫秒),具体数值在上下限中随机取值,若不指定默认间隔时间固定为1秒
min_wait = 3000
max_wait = 10000
locust脚本命令运行
代码语言:javascript复制# 方法一:脚本调试无头模式运行
locust -f locustfile.py --headless -u 10 -r 1 -t 30s
# -f:指定文件
# -u:指定用户量
# -r:每秒启动用户数
# -t:运行时间
# --headless:开启无头模式,即不使用UI界面操作
# 方法二:指定IP和端口启动,使用UI界面
locust -f locustfile.py --web-host 127.0.0.1 --web-port 8080
# 以上就是简单的启动locust脚本的方式,详细可以查看官方文档或者locust --help
locust的UI界面
- Number of new load test:设置模拟的用户总数
- Spawn rate (users spawned/second):每秒启动的虚拟用户数
- Host (e.g. http://www.example.com):被测目标地址
- Start swarming:执行locust脚本
测试结果页面
- Type:请求类型
- Name:请求路径
- Requests:当前完成的请求数量
- Fails:当前失败数量
- Median:响应时间中间值
- 90%ile(ms):正态分布90%的值在300ms内
- Average(ms):平均响应时间
- Min(ms):最小响应时间
- Max(ms):最大响应时间
- Average size (bytes):平均
- Current RPS:当前RPS
- Current Failures/s:当前失败的RPS/s
其他模块
- New test:点击该按钮对总虚拟用户数和每秒启动的虚拟用户数进行编辑重跑
- Statistics:类似JMeter的聚合报告
- Charts:测试结果变化趋势图
- Failures:失败请求的展示界面
- Exceptions:异常请求的展示界面
- Download Data:测试数据下载模块,提供三种类型的CSV格式下载,分别是:Statistics、responsetime、exceptions,还有总的测试报告Report
由于本篇是对性能测试理论知识的分享,想了解更多locust的高级使用方法,可以参考官方文档。
注意: 后端性能测试工具是实现后端性能测试的技术手段,不能简单地把使用后端性能测试工具等同于后端性能测试。一般是在测试脚本开发和测试执行阶段发挥作用。
六、性能测试流程
对于我们初学性能测试时,往往会陷入一个误区,那就是单纯的去学习性能测试工具,认为学会了工具的使用,就掌握了性能测试。这其实是大错特错的,工具的学习只是其中的一个阶段,而且是比较基础的一个阶段,在整个性能测试流程中,性能测试执行策略,性能场景和分析才是重中之重,也是最难的部分。
性能测试的学习路径可以分为五个阶段:
- 性能理论学习期
- 性能工具学习期
- 性能场景学习期
- 性能分析学习期
- 性能调优学习期
6.1 性能测试的前提
日常工作中,被问及何时进行性能测试时,往往很多人都是摸不着头脑,大多数情况下都是被动接受领导或者开发给的任务,才回去进行性能测试,很少人会主动出击,去思考在什么阶段进行性能测试,下面给出几点建议,当然大前提肯定是在功能测试之后,整个系统都是处于一种稳定的状态。
- 应用使用人数逐渐增多,性能问题频发,影响到用户的日常操作
- 需要提供很高稳定性的基础服务,这种一般都是系统的核心服务,支撑了多端的业务
- 改动了核心应用,担心对链路有影响
6.2 制定性能测试目标
- 第一种是以衡量系统的处理能力为核心目标
- 第二种检测系统的健壮性
- 第三种目标是系统的稳定性
- 第四种性能测试目标是专项能力是否达标
6.3 性能测试场景设计
1. 测试负载组成
- 虚拟用户脚本
- 各个虚拟用户脚本的并发数量
- 总的并发用户数
2. 负载策略
- 加压策略
- 减压策略
- 最大负载运行时间
- 延时策略
3. 资源监控范围定义
- 操作系统级别的监控指标
- 应用服务器的监控指标
- 数据库服务器的监控指标
- 缓存集群的监控指标
4. 终止方式
- 脚本出错时的处理方式
- 负载熔断机制
5. 负载产生规划
- 压力产生器数量
- 网络带宽要求
6.4 制定性能测试方案
性能测试方案是在正式进行性能测试之前的工作,主要包括:
- 制定性能测试目的
- 性能测试场景梳理
- 确定被测业务的部署结构
- 业务数据的分析
- 业务规则的分析确认
- 测试监控的内容确定
- 性能测试排期涉及人员
七、总结
今天谈到的性能测试知识,不过是九牛一毛。想要正真掌握性能测试还需要不断的亲身实践,扩大自己知识的广度和深度,对于初识性能测试且没有实际经验的我来说,这将是我以后学习,并加以实践的基石。
如果你觉得文章还不错,帮忙 点赞、转发、关注、留言 ,因为这将是我持续输出更多优质文章的最强动力!