【技术分享】性能测试类型与执行

1.性能测试目的与类型
性能测试:性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试
按照性能测试的目的不同,可以把性能测试分为3个类型。如果把被测系统比作1台车的话,比如车的设计时速为150km/h,
负载测试在于评估车在预期的负载下,其性能指标是否满足使用需求(发动机温度,车身是否晃动)。
压力测试在于评估这台车在性能发挥到极限时,能承载的最大时速(即发动机爆炸之前,能跑到的最快速度)。
稳定性测试,跑长途长时间高负载的运行,观察车的稳定性,路况突然变化的情况等。
| 类型 | 目的 | 简介 | 执行 |
| 负载测试 | 评估系统的能力 | 测试系统或软件应用程序在极端负载下的性能 | 设定并发用户量下,观察响应时间,和服务器的负载 |
| 压力测试 | 寻找系统瓶颈(以便调优),或者问题 | 就是在高负载的情况下,把系统搞坏,收集系统中的隐藏问题 | 在资源到达上限时能承载的最大并发量,来获得系统能提供的最大服务级别的测试 |
| 稳定性测试 | 验证稳定性、可靠性,鲁棒性 | 给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定 | 长时间已一定量的并发访问,以及突发的流量突增,验证服务器的指标 |
2.执行性能测试的3个阶段
性能测试工作流程有三个主要步骤:
- 测试之前,明确测试目的,创建测试规则(or脚本)
- 运行测试, 和收集测试数据和分析
- 测试报告.
2.1 脚本编写和工具选择
明确目的之后,设计出测试场景。然后根据测试场景创建对应的测试脚本。
压测工具有很多,这里简单介绍两个我常用的工具(locust 和 jmeter)
2.1.1 工具对比
| 工具 | Jmeter | Locust |
|---|---|---|
| 语言 | Java | Python |
| 易用性 | ✅有GUI客户端 ✅丰富的内置函数 ✅适合新手 ❌需要学习工具配置方法 | ❌需要有一定编程基础 ✅代码编写更简单 ✅参数化,断言,关联使用代码实现 |
| 扩展性 | ✅使用内置函数和第三方插件,支持JDBC,FTP,LDAP,SMTP等 | ❌内置支持http,其他协议需要自定义client |
| 性能 | 基于线程的并发 ✅支持分布式集群 | 基于协程 ✅占用更少的内存 ✅相同并发下发送TPS更高 ✅支持分布式集群 |
| 报告 | ✅丰富的报表 | ✅相对简单的报表 |
结论:
有python基础, Locust > Jmeter
无代码基础或有Java基础, Jmeter > Locust
2.1.2 工具介绍(locust脚本编写)
Locust 是一种易使用、可定制脚本,可扩展的性能测试工具。
特点:① 使用python代码来定制压测场景,无需UI工具和学习特定语法.
② 强大的扩展性, 开发者友好.
脚本:demo, 创建一个locustfile.py文件
# 1.引入locust包
import time
from locust import HttpUser, task, between
# 2.定义一个类继承自HttpUser, 执行时每一个用户对应这个类的一个实例, 实例的client属性对应一个HttpSession
class QuickstartUser(HttpUser):
# 3.设置每个task执行的间隔
wait_time = between(1, 2.5)
# 4.每一个用户启动时会执行on_start的方法.类似__init__ 的初始化的功能
def on_start(self):
self.client.post("/login", json={"username":"foo", "password":"bar"})
# 5.用@task装饰器装饰的函数, 是locust的核心, 执行测试时,每个用户按照task权重随机执行对应函数
@task
def hello_world(self):
self.client.get("/hello")
self.client.get("/world")
@task(3)
def view_items(self):
for item_id in range(10):
self.client.get(f"/item?id={item_id}", name="/item")
time.sleep(1)
2.1.3 工具介绍(locust的执行)
① 单机执行
# 默认会加载当前目录下的locustfile.py
$ locust
#使用 -f 指定选择脚本文件
$ locust -f locust_files/my_locust_file.py
运行locust后,会启动一个http服务,打开web界面可以配置测试参数信息

测试开始执行后,可以看到收集的测试数据和简单的曲线报表


② no-web 执行
可以直接在命令行中添加--headless指定 no-web执行,通过-H -u -r来指定参数
$ locust -f locust_files/my_locust_file.py -H api.test.com -u 400 -r 100 --headless
③ 分布式执行
master 模式
- --master-bind-host=X.X.X.X 设置master节点绑定的ip, 默认*
- --master-bind-port=5557 设置master节点绑定的端口, 默认 5557
- --expect-workers=X 启动master使用--headless模式下, master会等待X个worker上线之后才开始运行
$ locust -f my_locustfile.py --master
worker 模式
- --master-host=X.X.X.X 指定master节点的ip, 默认127.0.0.1
- --master-port=5557 指定master节点的端口, 默认5557
$ locust -f my_locustfile.py --worker --master-host=192.168.0.14 --master-port=5557
2.1.4 工具介绍(locust的高阶用法)
① 多用户类
多个用户类在同一个locustfile中, weight属性为多个类之间的权重
class WebUser(User):
weight = 3
...
class MobileUser(User):
weight = 1
...
执行的时候可指定1个或多个类
$ locust -f locust_files/my_locust_file.py WebUser MobileUser
② tag
可以通过@tag装饰器对task打标签
from locust import User, constant, task, tag
class MyUser(User):
wait_time = constant(1)
@tag('tag1')
@task
def task1(self):
pass
@tag('tag1', 'tag2')
@task
def task2(self):
pass
执行的时候使用--tag 或者--exclude-tags 指定特定任务
$ locust -f locust_files/my_locust_file.py --tags tag1 tag2
$ locust -f locust_files/my_locust_file.py --exclude-tags tag2
③ events
如果您需要在测试开始或停止时运行一些代码,可以使用 test_start 和 test_stop 事件
from locust import events
@events.test_start.add_listener
def on_test_start(environment, **kwargs):
print("A new test is starting")
@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
print("A new test is ending")
④ 自定义用户
task本质是一个动作, 除了内置支持的httpclient, 还可以自定义client完成其他操作. 例如一个Tcp协议的用户:
from client import TcpClient
from locust import User
def random_name():
...
class Sender(User):
wait_time = between(0.2, 0.5)
def on_start(self):
self.c = TcpClient(random_name())
self.c.connect(APP_ID, APP_SECRET, random_name())
self.c.login()
@task(100)
def send(self):
...
2.2 执行和分析
2.2.1 执行端指标 (QA)
1.并发数
2.TPS(每秒处理事务的能力)
3.响应时间(中位数,95分位,99分位)
4.错误率
2.2.2 服务端指标(QA & RD)
1.服务器设备性能:
CPU性能指标:利用率、负载( top )
Mem:内存性能指标( top, free ), (Disk:磁盘)[特定测试场景]¶
NetWork:流量带宽使用率( ip -s -h link ),TCP连接数( netstat )
2.其他服务性能:
中间件建立的线程池,监控线程状态
JVM性能指标,GC情况、Heap使用情况
2.3 测试报告
1.测试结论
描述系统存在的瓶颈点,或者系统表现符合预期.
2.测试背景
项目背景介绍,如:
XX项目上线后,注册用户量稳定增长,考虑到用户数量及数据的增多给服务器造成压力不可估计,因此计划对XX系统性能测试.
3.测试目的
明确测试目的,如:
1.在目前系统配置不变的情况下,在一定时间内,服务器在高负载情况下的性能行为表现,便于对系统可能存在的服务质量风险进行分析及评估.
2.保证目前SLA性能指标情况下,测试单个服务器可以承载的用户量最大值,便于对线上用户增长后,预期承载线上业务需要的资源扩容提供参考.
4.测试范围
包括可能影响的上下游系统,本系统内的功能模块,如:
1.消息系统-用户收发单聊群聊消息,用户拉取离线消息和历史消息,
2.文件系统-用户发送附件文件
5.测试环境配置信息
描述执行测试该项目硬件环境
6.测试数据和结果数据分析(结合图表)
总结
1.前期准备工作,场景准备和locust的使用方法
2.执行过程中监控,客户端,server和中间件
3.测试报告需要包含的内容
更多推荐
所有评论(0)