6000字Locust入门详解


目录
  • 一、Locust 性能测试
    • (一). 性能测试工具
      • 主流性能测试工具对比
      • 认识Locust
    • (二) locust 基本用法
      • 1.安装locust
      • 2.编写用例
      • 3. 启动测试
        • GUI 模式启动 locust
        • 命令行模式启动 locust
      • 4. locust概念
    • (三) locust 自定义压测协议 websocket
      • 什么是websocket协议 ?
      • 选择websocket 客户端
      • 创建WebSocketUser
    • (四). locust 核心组件
      • 核心组件: 2类 ,4个
      • 重要的属性:
    • (五). locust 扩展增强
      • 1. 录制用例
      • 2. 数据关联
      • 3. 参数化
      • 4. 检查点
      • 5. 思考时间
      • 6. 权重
      • 7. 集合点
      • 8. 分布式
        • 单机主从模式
        • 多机主从模式
      • 9. 资源监控
      • 10. docker 运行locust
      • (六)附外
        • 0. 进程、线程、协程区别
        • 1. 更多命令
        • 2. 学习路线
        • 4. 延伸阅读&知识库

    一、Locust 性能测试

    同步Notion :

    • https://young-glen.notion.site/Locust-994ec41de38744009814a63822b10eda

    问题引言:

    1. 主流性能工具对比
    2. 为什么要用locust进行性能测试
    3. 如何对http接口进行性能测试
    4. 如何对websocket接口进行性能测试
    5. locust性能测试报告分析
    6. locust 核心部件了解
    7. locust 主要用法详解

    (一). 性能测试工具

    主流性能测试工具对比

    • loadrunner : 收费 昂贵
    • jmeter: 开源(二次开发) 、基于java、多线程 、使用gui设计用例 ,xml保存 、录制工具

    loadRunner vs Jmeter

    loadrunner笔记:

    • https://mp.weixin.qq.com/s/V0wLFxrw4VIp9jTXVEKlag
    LoadRunner Jmeter
    非开源工具 开源工具
    C 语言 100% java 语言
    检查点(web_reg_find) 断言
    关联(web_reg_save_param) 关联(前置/后置处理器正则提取器)
    支持IP欺骗 不支持IP 欺骗
    测试结果分析图表功能强大(数据采集) 测试结果分析图表功能相对较弱,需依赖扩展插件
    重量级 轻量级
    安装复杂 安装简单
    跨平台
    根据不同负载生成不同数量并发用户 当前一个线程组只能生成一个
    性能 支持web端功能测试
    广泛支持业界各种标准协议、多种平台开发脚本 组件

    认识Locust

    定义

    Locust是一款易于使用的分布式负载测试工具,完全基于事件,即一个locust节点也可以在一个进程中支持数千并发用户,不使用回调,通过gevent使用轻量级过程(即在自己的进程内运行)。

    locust: 开源 、基于python ,非多线程(协程)、“用例即代码” ; 无录制工具、

    • python的一个库 ,需要python3.6 及以上环境支持
    • 可用做性能测试
    • 基于事件,用协程 进行性能测试
    • 支持 图形 、no-gui、 分布式等多种运行方式

    为什么选择locust

    • 基于协程 ,低成本实现更多并发

    • 脚本增强(“测试即代码”)

    • 使用了requests发送http请求

    • 支持分布式

    • 使用Flask 提供WebUI

    • 有第三方插件、 易于扩展

    (二) locust 基本用法

    约定大于配置

    1.安装locust

    pip install  locust
    
    locust -v 
    

    2.编写用例

    test_xxx (一般测试框架约定)

    dockerfile (docker约定)

    locustfile.py (locust约定)

    # locustfile.py
    

    eg: 入门示例

    from locust import HttpUser, task, between
    
    
    # User  ?
    # function  包装task
    class MyHttpUser(HttpUser):
        wait_time = between(1, 2)  # 执行任务 等待时长   检查点 思考时间
    
        @task
        def index_page(self):
            self.client.get("https://baidu.com/123")
            self.client.get("https://baidu.com/456")
    
        pass
    

    总结三步:

    1. 创建locust.HttpUser 之类
    2. 为待测试用例添加@locust.task 装饰器
    3. 使用self.client 发送请求
    4. 指定 wait_time 属性

    3. 启动测试

    Locust官方文档(API)解读(全)

    • https://cloud.tencent.com/developer/article/1594240#

    GUI 模式启动 locust

    启动locust

    ? 访问:http://[::1]:8089/

    指标详解:

    - Number of users  模拟用户数
    - Spawn rate  : 生产数 (每秒)、   =>jmeter : Ramp-Up Period (in seconds)
    - Host (e.g. http://www.example.com)  => 取决脚本中 绝对地址
    - ![](https://s3.bmp.ovh/imgs/2022/06/14/22e82961a5609f42.png)
    
    • WebUI 模块说明:
      • New test:点击该按钮可对模拟的总虚拟用户数和每秒启动的虚拟用户数进行编辑;
      • Statistics:类似于jmeter中Listen的聚合报告;
      • Charts:测试结果变化趋势的曲线展示图,分别为每秒完成的请求数(RPS)、响应时间、不同时间的虚拟用户数;
      • Failures:失败请求的展示界面;
      • Exceptions:异常请求的展示界面;
      • Download Data:测试数据下载模块, 提供三种类型的CSV格式的下载,分别是:Statistics、responsetime、exceptions;

    命令行模式启动 locust

    locust -f locustfile.py --headless -u 500 -r 10  --host 123  -t 1h5m
    

    ? 框架是通过命令locust运行的,常用参数有:

    • -H:指定测试的主机地址(注:会覆盖Locust类指定的主机地址)
    • -f:指定测试脚本地址(注:脚本中必须包含一个Locust的衍生类)
    • --no-web:不启动web网页,而是直接开始运行测试,需提供属性-c和-r
    • -u:并发的用户数,与--no-web一起使用
    • -r:每秒启动的用户数,与--no-web一起使用
    • -t:运行时间(单位:秒),与--no-web一起使用
    • -L:日志级别,默认为INFO
      调试命令:locust -f **.py --no-web -u 1 -t 1
      运行命令:locust -f **.py

    4. locust概念

    1. 父类是个User ?

      表示要生成进行负载测试的系统的 HTTP“用户”。

      • 性能测试 模拟真实用户
      • 每个user相当于一个协程链接 ,进行相关系统交互操作
    2. 为什么方法,要包装为task

      • task 表示用户要进行的操作

        • 访问首页 → 登录 → 增、删改查 → homPage
      • TaskSet : 定义用户将执行的一组任务的类。测试任务开始后,每个Locust用户会从TaskSet中随机挑选 一个任务执行

      • 具体的内容: 方法的代码

         class MyHttpUser(HttpUser):   #用户
            # wait_time = lambda self: random.expovariate(1)*1000
            wait_time = between(1, 2)  # 执行任务 等待时长   检查点 思考时间
        
            @task
            def index_page(self):   # 用户执行操作
                self.client.get("https://baidu.com/123")  #服务错误、网络错误
                self.client.get("https://baidu.com/456")
                # 断言 、 业务错误
        

    (三) locust 自定义压测协议 websocket

    locust 并非 http 接口测试工具 , 只是内置了 “HttpUser” 示例 ,可以测试任何协议: websocket 、socket 、mqtt (webAPP、Hybrid、Html5 、桌面浏览器) 、rpc

    什么是websocket协议 ?

    WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。ws长连接、 和http有本质不同 ;

    客户端发起,服务器可能接受或拒绝切换到新协议。客户端可使用常用的协议(如HTTP / 1.1)发起请求,请求说明需要切换到HTTP / 2或甚至到WebSocket

    一句话概述:协议“使用HTTP进行握手, 后使用TCP进行会话” 的全双工协议

    选择websocket 客户端

    目前pypi , 2个ws库

    • websockets: 提供client , 提供了server ; 使用async 语法
    • websocket_client: 仅提供client 、使用(非async)同步语法
    1. 安装 pip install websocket_client

    2. 使用

      import asyncio
      import websockets
      
      async def hello():
          async with websockets.connect('ws://localhost:8765') as websocket:
              name = input("What's your name? ")
      
              await websocket.send(name)
              print(f" send:>>> {name}")
      
              greeting = await websocket.recv()
              print(f" recv: <<< {greeting}")
      
      asyncio.get_event_loop().run_until_complete(hello())
      

      创建WebSocketUser

      1. 创建专用客户端链接

      2. 设计统计结果

      3. 设定成功、失败条件

        pyfile:

      TimeoutError(10060, '[WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。')
      1.请求服务器的反爬机制导致的,请求不被接受的 ; ip限制
      → 网页访问验证 -
      2. http的连接数超过最大限制。
      headers的Connection参数默认为keep-alive,之前所有请求的链接都一直存在,占用了后续的链接请求
      3. 网站服务器太差 → 修改中间件配置(SLB、nginx 、ApiGateway 熔断、限流 ~
      →timeout 超时时间
      ........... 9大策略和6大指标 、
      ........... 硬件(计算机体系机构)、操作系统(OS\JVM)、文件系统、网络通信、数据库系统、中间件(transaction、message、app)、应用程序本身

    本地:netsh winsock reset → 重启

    ? 初步结果:
    ?
    ? 1. RPS xxxx 左右
    ?
    ? 2. 最大用户数 xxx
    ?
    ? > 表示:当前允许最大用户数请求,但是无法全部返回结果

    常见错误 可能分析原因
    TPS波动较大 网络波动其他服务资源竞争以及垃圾回收问题
    高并发下大量报错 短连接导致的端口被完全占用以及线程池最大线程数配置较小超时时间较短导致。
    集群类系统,各服务节点负载不均衡 SLB服务设置了会话保持
    并发数不断增加,TPS上不去,CPU使用率较低 SQL没有创建索引/SQL语句筛选条件不明确、代码中设有同步锁,高并发时出现锁等待;
    connection reset、服务重启、timeout 参数配置、服务策略、阻塞及各种锁导致

    (四). locust 核心组件

    核心组件: 2类 ,4个

    • User : 在locust中User类表示一个用户。locust将为每一个被模拟的用户生成一个User类实例,而我们可以在User类中定义一些常见的属性来定义用户的行为。

      • HttpUser
    • Task: 用户行为

      • SequentialTaskSet
      • TaskSet:
        • tasks属性将多个TaskSet子类嵌套在一起
        • 类中相互嵌套
        • User类中嵌入TaskSet类,作为User的子类
    • Events : locust提供的事件钩子,用于一些再运行过程中执行特定时间的操作。

    重要的属性:

    • wait_time

      ? > 三种时间间隔表达式

      • 固定时间, 由python-requests。如果您计划以非常高的吞吐量运行测试并且运行 Locust 的硬件有限,那么它有时效率不够。Locust 还附带一文读懂什么是进程、线程、协程

        • https://cloud.tencent.com/developer/article/1546730
      • Processes, threads, and coroutines
        • https://subscription.packtpub.com/book/programming/9781788627160/1/ch01lvl1sec02/processes-threads-and-coroutines#:~:text=Processes%2C threads%2C and coroutines When you start an,detail the relationship between processes%2C threads%2C and coroutines.
      • Comparison of Process , Thread and Coroutines
        • https://functional.works-hub.com/learn/comparison-of-process-thread-and-coroutines-becf6

      1. 更多命令

      如果Locust文件位于与locustfile.py在不同的子目录/或者文件名不一样,则使用参数-f+文件名:
      $ locust -f locust_files/my_locust_file.py
      要在多个进程中运行Locust,我们可以通过指定--master:
      $ locust -f locust_files/my_locust_file.py --master
      启动任意数量的从属进程:
      $ locust -f locust_files/my_locust_file.py --slave
      如果要在多台机器上运行Locust,则在启动从属服务器时还必须指定主服务器主机(在单台计算机上运行Locust时不需要,因为主服务器主机默认为127.0.0.1):
      $ locust -f locust_files/my_locust_file.py --slave --master-host=192.168.0.100
      还可以在配置文件(locust.conf或~/.locust.conf)或以LOCUST_前缀的env vars中设置参数
      例如:(这将与上一个命令执行相同的操作)
      $ LOCUST_MASTER_HOST=192.168.0.100 locust
      
      注意:要查看所有可用选项,请键入:locust —help
      

      2. 学习路线

      https://docs.locust.io/en/stable/what-is-locust.html

      3. WebSocket与HTTP的关联和差异

      相同:

      1. 建立在TCP之上,通过TCP协议来传输数据。
      2. 都是可靠性传输协议
      3. 都是应用层协议。

      不同:

      1. WebSocket是HTML5中的协议,支持持久连接,HTTP不支持持久连接
      2. HTTP是单向协议,只能由客户端发起,做不到服务器主动向客户端推送信息

      4. 延伸阅读&知识库

      参考资料:https://github.com/locustio/locust/wiki/Articles