Python 模块 locust 性能测试

简介

        locust 是 Python 的一个开源的负载测试工具,用于测试网络应用程序的性能和可伸缩性。它使用Python编写,并提供了一个简单易用的语法来定义和执行负载测试。locust模块允许用户模拟大量并发用户并观察系统在高负载下的响应情况。

目录

1. 基本用法

1.1. 基础代码

1.2. 执行方法

1.2.1. web 界面执行

1.2.2. 命令执行

2. 多用例调度

2.1. 数据关联

2.1.1. 自定义辅助方法

2.1.2. 自定义初始操作

2.1.3. 任务依赖方法

2.2. 执行顺序

2.3. 线程分配

3. 分布式压测


                              

1. 基本用法

1.1. 基础代码

from locust import HttpUser, task, between

class MyUser(HttpUser):
    # 设置用户在执行任务时等待 1~3 秒
    wait_time = between(1, 3)

    @task   #标记为测试任务
    def test1(self):
        # 发送 get 请求
        response = self.client.get('xxx')
        # 通过状态码来断言
        assert response.status_code == 200

                                       

post 请求方法

data = {"username": "yt", "password": "123456"}
self.client.post("xxx", json=data)  # 发送POST请求到指定URL,并附带JSON数据

get 带头部信息

headers = {"Authorization": "yt token123"}
self.client.get("xxx", headers=headers)  # 发送带头部的GET请求

                                       

1.2. 执行方法

1.2.1. web 界面执行

1、执行命令

locust -f 文件

                                       

2、通过提示的地址打开浏览器

提示地址:http://0.0.0.0:8089

把 0.0.0.0 改成 localhost

http://localhost:8089/

                                       

3、查看结果

大项选择

                                       

统计数据(Statistics)

  • Requests:总请求数
  • Fails:总失败数
  • Median (ms):中位数响应时间(将所有观察值按从小到大排序后,正好处于中间位置的值)
  • 90%ile (ms):90% 的响应时间(有 90% 的请求的响应时间小于或等于该值)
  • 99%ile (ms):99% 的响应时间(有 99% 的请求的响应时间小于或等于该值)
  • Average (ms):平均响应时间
  • Min(ms):最小响应时间
  • Max(ms):最大响应时间
  • Average size (bytes):请求返回的平均响应内容大小
  • Current RPS:当前的每秒请求数
  • Current Failures/s: 当前每秒失败请求数

                                       

图表信息(Charts)

每秒总请求数(Total Requests per Second)

  • RPS:当前请求数
  • Failures/s:当前失败数

                                       

响应时间(Response Times (ms))

  • Median Response Time:中位数响应时间
  • 95% percentile:95% 的响应时间

                                       

用户数(Number of Users)

                                       

1.2.2. 命令执行

常用参数选项

-f:指定Python测试文件
-H:设置主机地址
-u:设置用户数
-r:每秒生成n个用户
-t:指定测试时长(例如:300s, 20m, 3h, 1h30m)
-P:指定web界面端口
-l:显示可能的User类列表并退出

web UI 参数选项

--web-host:要绑定web接口的主机。默认为'*'(所有接口)
--web-port:指定web界面端口
--headless:不使用web界面测试,直接启动测试
--autostart:直接启动测试,不禁用web
--autoquit:执行运行结束后n秒完全退出。只能与——autostart一起使用。默认情况下,在使用CTRL+C关闭Locustl之前,它将一直运行
--web-auth:打开web界面的基本验证。基本格式为 username:password
--tls-cert:用于通过HTTPS提供服务的TLS证书的可选路径
--tls-key:用于通过HTTPS提供服务的TLS私钥的可选路径

分布式压测选项

--master:将locust设置为以分布式模式运行,并将此进程设置为主进程
--master-bind-host:master绑定的接口(主机名、ip)(默认:*(所有可用接口))
--master-bind-port:locust绑定的端口(默认:5557)
--expect-workers:在开始测试之前(仅当使用——headless/autostart时),master应该连接多少worker
--expect-workers-max-wait:主节点等待备节点的时间(默认:永远等待)

--worker:将locust设置为以分布式模式运行,并将此进程作为辅助进程
--master-host:指定主机或IP地址(默认:127.0.0.1)
--master-port:指定要连接的端口。默认为5557。

输出信息选项

--html:将HTML报告存储到指定的文件路径
--csv:以CSV格式将当前请求状态存储到文件中
--csv-full-history:将每个统计条目以CSV格式存储到统计历史记录中。必须指定'--csv'
--print-stats:在控制台中打印统计信息
--only-summary:仅打印摘要统计信息
--reset-stats:开始之前重置所有的统计数据(包括请求数、响应时间等),分布式需要同时设置主备。
               该参数主要用于在连续运行多个测试场景时,确保每个测试都从零开始计算统计信息,以避免之前的数据对当前测试的影响。

输出日志选项

--skip-log-setup:禁用locust的日志设置,由Locust测试或Python默认值提供。
--loglevel:设置日志级别(默认:INFO),可选 DEBUG、INFO、WARNING、ERROR、CRITICAL
--logfile:指定日志文件的路径。如果没有设置,日志将转到stderr

                                       

直接使用命令执行

locust -f tmp1.py --host=abc --headless -u 10 -r 1 -t 10s
  • -f:指定测试文件 tmp1.py
  • --host:指定访问地址(代码中已写死地址,这里随便写都行)
  • --headless:禁用web,直接测试
  • -u:设置10个总用户数
  • -r:每秒增加1个用户
  • -t:总共执行10秒

                                       

将命令放入 Python 文件

import os

if __name__ == '__main__':
    file_path = os.path.abspath(__file__)
    os.system(f'locust -f {file_path} --host=abc --headless -u 1 -t 1s')

                                       

                                       

2. 多用例调度

2.1. 数据关联

2.1.1. 自定义辅助方法

方法结构

代码如下

from locust import HttpUser, task

class MyUser(HttpUser):
    # 定义一个空的token
    token = ""

    '''定义测试用例'''
    @task
    def test1(self):
        # 先调用登录方法
        self.login()
        # 再调用查询信息的方法
        self.query_information()

    '''定义登录方法'''
    def login(self):
        # 使用post请求登录界面
        response = self.client.post("/login", json={"username": "yt", "password": 123456})
        # 获取登录的token值
        self.token = response.json()["token"]

    '''定义登录之后的查询信息'''
    def query_information(self):
        # 通过登录方法获取的token值,组成headers
        headers = {"Authorization": f"yt {self.token}"}
        # 查询个人信息
        self.client.post("xxx", headers=headers, json={"data": "data"})

                                       

2.1.2. 自定义初始操作

方法结构

代码如下

from locust import HttpUser, task

class MyUser(HttpUser):
    # 定义一个空的token
    token = ""

    """定义一个开始方法,on_start是固定名称"""
    def on_start(self):
        # 在测试前进行登录,并获取token值
        response = self.client.post("/login", json={"username": "yt", "password": 123456})
        self.token = response.json()["token"]

    """封装测试用例"""
    @task
    def test1(self):
        # 通过测试前获取的token代入headers
        headers = {"Authorization": f"yt {self.token}"}
        # 执行post请求测试
        self.client.post("xxx", headers=headers, json={"data": "data"})

                                       

2.1.3. 任务依赖方法

方法结构

代码如下

from locust import HttpUser, task

class MyUser(HttpUser):
    # 定义一个空的token
    token = ""

    """定义一个登录测试方法"""
    @task
    def login(self):
        # 使用post请求登录界面
        response = self.client.post("/login", json={"username": "yt", "password": 123456})
        # 获取登录token值
        self.token = response.json()["token"]

    """定义一个登录后查询信息的方法"""
    @task
    def query_information(self):
        # 通过登录方法获取的token值,组成headers
        headers = {"Authorization": f"yt {self.token}"}
        # 查询个人信息
        self.client.post("xxx", headers=headers, json={"data": "data"})

                                       

2.2. 执行顺序

使用 tasks = [ ] 来指定任务函数的执行顺序。任务函数会循环执行,按照列表中的顺序进行调度。

【错误示例】直接使用 HttpUser 方法不能保证顺序

from locust import HttpUser, task

class MyUser(HttpUser):
    @task
    def test1(self):
        print('test1  --登录')

    @task
    def test2(self):
        print('test2  --查询商品信息')

    @task
    def test3(self):
        print('test3  --查看评价')

    tasks = [test1, test3, test2]

                                       

使用 SequentialTaskSet 方法(从上往下顺序执行)

from locust import HttpUser, task, SequentialTaskSet

class MyUser(HttpUser):

    """定义一个顺序执行的类,方法从上往下的执行"""
    @task
    class MySequentialTaskSet(SequentialTaskSet):

        @task
        def test1(self):
            print('test1  --登录')

        @task
        def test2(self):
            print('test2  --查询商品信息')

        @task
        def test3(self):
            print('test3  --查看评价')

    # 在user类中,指定类的顺序
    tasks = [MySequentialTaskSet]

                                       

2.3. 线程分配

  • 使用 @task 装饰器设置权重(权重为1,执行1次;权重为2,执行2次...)。设置权重后 tasks 指定的顺序将会受到影响。

示例(测试前登录,登录后多次调用其他方法)

from locust import HttpUser, task

class MyUser(HttpUser):
    """测试前调用登录方法"""
    def on_start(self):
        self.test1()

    """封装一个登录方法"""
    def test1(self):
        print('test1  --登录')

    """封装一个查询商品信息的方法"""
    @task(3)    # 设置权重为3,执行3次
    def test2(self):
        print('test2  --查询商品信息')

    """封装一个查看评价的方法"""
    @task(5)    # 设置权重为5,执行5次
    def test3(self):
        print('test3  --查看评价')

    """指定执行顺序,基本无效"""
    tasks = [test2, test3]

                                       

使用 SequentialTaskSet 方法指定顺序,并设置权重

from locust import HttpUser, task, SequentialTaskSet, TaskSet

class MyUser(HttpUser):

    """定义一个顺序执行的类"""
    @task
    class MySequentialTaskSet(SequentialTaskSet):

        @task(1)    # 执行1次
        def test1(self):
            print('test1  --登录')

        @task(5)    # 执行5次
        def test2(self):
            print('test2  --查询商品信息')

        @task(3)    # 执行3次
        def test3(self):
            print('test3  --查看评价')

                                       

                                       

3. 分布式压测

方法简单,步骤如下

  • 编写 locust 脚本 → 主节点执行 →  从节点执行 → web 端启动

1、编写 locust 脚本(根据实际情况写,方法同上示例)

2、主节点启动 locust 100个线程

locust -f <Python文件> --master --users 100

3、从节点启动 locust 50个线程

locust -f <Python文件> --slave --master-host=<主节点的IP> --clients 50

4、登录 web 界面执行即可(见目录 1.2.1)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring5.2.x 源码使用Gradle成功构建

一 前置准备 1 Spring5.2.x下载 1.1 Spring5.2.x Git下载地址 https://gitcode.net/mirrors/spring-projects/spring-framework.git 1.2 Spring5.2.x zip源码包下载&#xff0c;解压后倒入idea https://gitcode.net/mirrors/spring-projects/spring-framework/-/…

Layui实现OA会议系统之会议管理模块总合

目录 一、项目背景 二、项目概述 1. 概述 2. 环境搭建 3. 工具类引用 4. 功能设计 4.1 会议发布 4.2 我的会议 4.3 会议审批 4.4 会议通知 4.5 待开会议 4.6 历史会议 4.7 所有会议 5. 性能优点 5.1 兼容性好 5.2 可维护性和可扩展性 5.3 轻量灵活 5.4 模块化设计…

[BabysqliV3.0]phar反序列化

文章目录 [BabysqliV3.0]phar反序列化 [BabysqliV3.0]phar反序列化 开始以为是sql注入 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ST1jvadM-1691302941344)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032140269.png)…

SQL-每日一题【1179. 重新格式化部门表】

题目 部门表 Department&#xff1a; 编写一个 SQL 查询来重新格式化表&#xff0c;使得新的表中有一个部门 id 列和一些对应 每个月 的收入&#xff08;revenue&#xff09;列。 查询结果格式如下面的示例所示&#xff1a; 解题思路 1.题目要求我们重新格式化表&#xff0c;…

【Linux】五、进程

一、冯诺依曼体系结构 存储器&#xff1a;指的是内存&#xff1b; 输入设备&#xff1a;键盘、摄像头、话筒&#xff0c;磁盘&#xff0c;网卡&#xff1b; 输出设备&#xff1a;显示器、音响、磁盘、网卡&#xff1b; 中央处理器&#xff08;CPU&#xff09;&#xff1a;运算器…

一、8.分页

当物理内存不够时就把不常用的内存暂时存入磁盘&#xff0c;并且描述符的P位置0&#xff0c;把要使用的段放入内存&#xff0c;描述符P位置1 但是这种方式会产生大量内存碎片&#xff0c;影响内存分配效率 设想一个虚拟内存&#xff0c;每隔任务都有他独立的虚拟内存&#xf…

【编译原理】五、简单四则运算的代码实现

1. 前言 前面说了那么多BNF的相关理论知识&#xff0c;实际上就是为了一个目的&#xff1a; 描述语法规则 描述语法规则是一切的开始。最终&#xff0c;还是要用代码来实现。 如果对于BNF仍然是一头雾水&#xff0c;也没关系&#xff0c;因为我们的最终目的是编写解析器&…

用Abp实现找回密码和密码强制过期策略

用户找回密码&#xff0c;确切地说是重置密码&#xff0c;为了保证用户账号安全&#xff0c;原始密码将不再以明文的方式找回&#xff0c;而是通过短信或者邮件的方式发送一个随机的重置校验码&#xff08;带校验码的页面连接&#xff09;&#xff0c;用户点击该链接&#xff0…

.dex文件转换成.class文件,.class文件转成java文件

.dex文件转换成.class文件 什么是.dex文件 dex文件是Android系统的可执行文件,包含应用程序的全部操作指令以及运行时数据。 由于dalvik是一种针对嵌入式设备而特殊设计的java虚拟机,所以dex文件与标准的class文件在结构设计上有着本质的区别。 当java程序编译成class后,还需…

解决一个Sqoop抽数慢的问题,yarn的ATSv2嵌入式HBASE崩溃引起

新搭建的一个Hadoop环境&#xff0c;用Sqoop批量抽数的时候发现特别慢&#xff0c;我们正常情况下是一个表一分钟左右&#xff0c;批量抽十几个表&#xff0c;也就是10分钟的样子&#xff0c;结果发现用了2个小时&#xff1a; 查看yarn日志 发现有如下情况&#xff1a; 主要有两…

《JeecgBoot系列》JeecgBoot(ant-design-vue) 识别字段中指定内容并修改该行文字颜色

JeecgBoot(ant-design-vue) 识别字段中指定内容并修改该行文字颜色 需求&#xff1a;将生产工厂是配件工厂的行改变颜色标注 一、修改table组件内容 在<a-table></a-table>内添加:rowClassName"tableRowClass" <a-table>...:rowClassName"t…

动态路由协议 ospf

动态路由协议的分类 rip : 距离矢量路由协议&#xff08;容易产生环路&#xff09;ospf&#xff1a; 链路状态路由协议&#xff08;比较耗费资源&#xff0c;但是链路准确性好&#xff09;bgp&#xff1a; 外部网关协议 RIP OSPF LSA泛洪 LSDB维护 SPF计算&#xff08;最短路…

前端笔记html-layer使用

layer.open方法 layer.open({type:2, //可传入的值有&#xff1a;0&#xff08;信息框&#xff0c;默认&#xff09;1&#xff08;页面层&#xff09;2&#xff08;iframe层&#xff09;3&#xff08;加载层&#xff09;4&#xff08;tips层&#xff09;title: title,content:[…

postgis mvt矢量切片 django drf mapboxgl

postgis mvt矢量切片 django drf mapboxgl 目录 0.前提 1.sql代码 2.django drf后端服务代码 3.具体的应用&#xff08;整体代码&#xff09; 4.参考 0.前提 [1] 静态的矢量切片可以采用 tippecanoe 生成&#xff0c;nginx代理&#xff0c;这种数据是不更新的&#xff1b…

Element的Dialog+Form使用问题

在Element的Dialog中使用表单时&#xff0c;可能会出现以下问题 无法清空表单校验 <el-dialog title"新建资产" :visible.sync"addAssetsFormVisible" close"resetForm(addAssets)">resetForm (formName) {this.$refs[formName].resetFie…

LeetCode724. 寻找数组的中心下标

题干 给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#xff0c;那么左侧数之和视为 0 &#xff0c;因为在下标的左侧不存在元素。…

高德地图实现点聚合功能的详细步骤

目录 介绍准备工作1.注册并登录高德地图开放平台&#xff0c;申请密钥2.在Vue项目中安装高德地图的相关库/插件。 一、点聚合1.引入高德地图API<font color purple>initializeMap()<font color purple>loadData()<font color purple>createMarkerClustere…

K8S系列文章之 自动化运维利器 Fabric

Fabric 主要用在应用部署与系统管理等任务的自动化&#xff0c;简单轻量级&#xff0c;提供有丰富的 SSH 扩展接口。在 Fabric 1.x 版本中&#xff0c;它混杂了本地及远程两类功能&#xff1b;但自 Fabric 2.x 版本起&#xff0c;它分离出了独立的 Invoke 库&#xff0c;来处理…

SpringBoot第30讲:SpringBoot集成MySQL - MyBatis-Plus基于字段隔离的多租户

SpringBoot第30讲&#xff1a;SpringBoot集成MySQL - MyBatis-Plus基于字段隔离的多租户 本文是SpringBoot第30讲&#xff0c;主要介绍 MyBatis-Plus的基于字段隔离的多租户实现&#xff0c;以及MyBatis-Plus的基于字段的隔离方式实践和原理。 文章目录 SpringBoot第30讲&#…

Qt5.13引入QtWebApp的模块后报错: error C2440: “reinterpret_cast”: 无法从“int”转换为“quintptr”

1、开发环境 Win10-64 qt5.13 msvc2015-64bit-release 2、报错 新建一个demo工程。 引入QtWebApp的httpserver、logging、templateengine三个模块后。 直接运行&#xff0c;&#xff0c;此时报错如下&#xff1a; E:\Qt5.13.1\install\5.13.1\msvc2015_64\include\QtCore…