性能测试工具Locust


 1.简介

  Locust 是一个易于使用,分布式,用户负载测试工具。它用于负载测试 web 站点(或其他系统),并计算出一个系统可以处理多少并发用户。在测试期间,一大群虚拟用户访问你的网站。

  每个测试用户的行为由您定义,集群过程由 web UI 实时监控。这将帮助您在让真正的用户进入之前进行测试并识别代码中的瓶颈。

  Locust 完全是基于事件的,因此在一台机器上支持数千个并发用户是可能的。与许多其他基于事件的应用程序不同,它不使用回调。相反它通过 gevent 使用轻量级协程。

  这允许您用 Python 编写非常有表现力的场景,而不用回调使代码复杂化。

  官网: https://www.locust.io/

  官方文档:https://docs.locust.io/en/latest/

2.Locust安装

2.1安装方式

  • 控制台安装

    C:\特昂糖>pip3 install locust
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    Collecting locust
      Using cached locust-2.8.2-py3-none-any.whl (803 kB)
    Collecting typing-extensions>=3.7.4.3
      Downloading typing_extensions-4.1.1-py3-none-any.whl (26 kB)
    Collecting geventhttpclient>=1.5.1
      Downloading geventhttpclient-1.5.3-cp39-cp39-win_amd64.whl (36 kB)
    Requirement already satisfied: flask>=2.0.0 in f:\python3\lib\site-packages (from locust) (2.0.2)
    Collecting Flask-BasicAuth>=0.2.0
      Downloading Flask-BasicAuth-0.2.0.tar.gz (16 kB)
      Preparing metadata (setup.py) ... done
    Collecting roundrobin>=0.0.2
      Downloading roundrobin-0.0.2.tar.gz (2.4 kB)
      Preparing metadata (setup.py) ... done
    Collecting gevent>=20.9.0
      Downloading gevent-21.12.0-cp39-cp39-win_amd64.whl (1.6 MB)
         ---------------------------------------- 1.6/1.6 MB 537.0 kB/s eta 0:00:00
    Requirement already satisfied: requests>=2.23.0 in f:\python3\lib\site-packages (from locust) (2.26.0)
    Requirement already satisfied: Werkzeug>=2.0.0 in f:\python3\lib\site-packages (from locust) (2.0.2)
    Collecting ConfigArgParse>=1.0
      Downloading ConfigArgParse-1.5.3-py3-none-any.whl (20 kB)
    Collecting pywin32
      Downloading pywin32-303-cp39-cp39-win_amd64.whl (9.3 MB)
         ---------------------------------------- 9.3/9.3 MB 536.5 kB/s eta 0:00:00
    Collecting msgpack>=0.6.2
      Downloading msgpack-1.0.3-cp39-cp39-win_amd64.whl (69 kB)
         ---------------------------------------- 69.7/69.7 KB 540.9 kB/s eta 0:00:00
    Collecting psutil>=5.6.7
      Downloading psutil-5.9.0-cp39-cp39-win_amd64.whl (245 kB)
         ---------------------------------------- 245.6/245.6 KB 578.3 kB/s eta 0:00:00
    Collecting pyzmq>=22.2.1
      Downloading pyzmq-22.3.0-cp39-cp39-win_amd64.whl (1.0 MB)
         ---------------------------------------- 1.0/1.0 MB 481.3 kB/s eta 0:00:00
    Collecting Flask-Cors>=3.0.10
      Downloading Flask_Cors-3.0.10-py2.py3-none-any.whl (14 kB)
    Requirement already satisfied: click>=7.1.2 in f:\python3\lib\site-packages (from flask>=2.0.0->locust) (8.0.3)
    Requirement already satisfied: Jinja2>=3.0 in f:\python3\lib\site-packages (from flask>=2.0.0->locust) (3.0.3)
    Requirement already satisfied: itsdangerous>=2.0 in f:\python3\lib\site-packages (from flask>=2.0.0->locust) (2.0.1)
    Requirement already satisfied: Six in f:\python3\lib\site-packages (from Flask-Cors>=3.0.10->locust) (1.16.0)
    Collecting zope.event
      Downloading zope.event-4.5.0-py2.py3-none-any.whl (6.8 kB)
    Requirement already satisfied: cffi>=1.12.2 in f:\python3\lib\site-packages (from gevent>=20.9.0->locust) (1.15.0)
    Collecting zope.interface
      Downloading zope.interface-5.4.0-cp39-cp39-win_amd64.whl (210 kB)
         ---------------------------------------- 210.7/210.7 KB 329.2 kB/s eta 0:00:00
    Requirement already satisfied: setuptools in f:\python3\lib\site-packages (from gevent>=20.9.0->locust) (56.0.0)
    Collecting greenlet<2.0,>=1.1.0
      Downloading greenlet-1.1.2-cp39-cp39-win_amd64.whl (101 kB)
         ---------------------------------------- 101.9/101.9 KB 266.5 kB/s eta 0:00:00
    Requirement already satisfied: certifi in f:\python3\lib\site-packages (from geventhttpclient>=1.5.1->locust) (2021.10.8)
    Collecting brotli
      Downloading Brotli-1.0.9-cp39-cp39-win_amd64.whl (383 kB)
         ---------------------------------------- 383.4/383.4 KB 404.7 kB/s eta 0:00:00
    Requirement already satisfied: urllib3<1.27,>=1.21.1 in f:\python3\lib\site-packages (from requests>=2.23.0->locust) (1.26.7)
    Requirement already satisfied: idna<4,>=2.5 in f:\python3\lib\site-packages (from requests>=2.23.0->locust) (3.3)
    Requirement already satisfied: charset-normalizer~=2.0.0 in f:\python3\lib\site-packages (from requests>=2.23.0->locust) (2.0.7)
    Requirement already satisfied: pycparser in f:\python3\lib\site-packages (from cffi>=1.12.2->gevent>=20.9.0->locust) (2.21)
    Requirement already satisfied: colorama in f:\python3\lib\site-packages (from click>=7.1.2->flask>=2.0.0->locust) (0.4.4)
    Requirement already satisfied: MarkupSafe>=2.0 in f:\python3\lib\site-packages (from Jinja2>=3.0->flask>=2.0.0->locust) (2.0.1)
    Using legacy 'setup.py install' for Flask-BasicAuth, since package 'wheel' is not installed.
    Using legacy 'setup.py install' for roundrobin, since package 'wheel' is not installed.
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    Installing collected packages: roundrobin, pywin32, msgpack, brotli, zope.interface, zope.event, typing-extensions, pyzmq, psutil, greenlet, ConfigArgParse, gevent, geventhttpclient, Flask-Cors, Flask-BasicAuth, locust
      Running setup.py install for roundrobin ... done
      Running setup.py install for Flask-BasicAuth ... done
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    Successfully installed ConfigArgParse-1.5.3 Flask-BasicAuth-0.2.0 Flask-Cors-3.0.10 brotli-1.0.9 gevent-21.12.0 geventhttpclient-1.5.3 greenlet-1.1.2 locust-2.8.2 msgpack-1.0.3 psutil-5.9.0 pywin32-303 pyzmq-22.3.0 roundrobin-0.0.2 typing-extensions-4.1.1 zope.event-4.5.0 zope.interface-5.4.0
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
    WARNING: Ignoring invalid distribution -ip (f:\python3\lib\site-packages)
  • 通过GitHub上克隆项目安装

    地址:https://github.com/locustio/locust    然后执行locust> python setup.py install

2.2验证是否安装成功

  cmd控制台   >>locust --help

C:\Users\特昂糖>locust --help
Usage: locust [OPTIONS] [UserClass ...]

Common options:
  -h, --help            show this help message and exit
  -f LOCUSTFILE, --locustfile LOCUSTFILE
                        Python module file to import, e.g. '../other.py'. Default: locustfile
  --config CONFIG       Config file path
  -H HOST, --host HOST  Host to load test in the following format: http://10.21.32.33
  -u NUM_USERS, --users NUM_USERS
                        Peak number of concurrent Locust users. Primarily used together with --headless or
                        --autostart. Can be changed during a test by keyboard inputs w, W (spawn 1, 10 users) and s, S
                        (stop 1, 10 users)
  -r SPAWN_RATE, --spawn-rate SPAWN_RATE
                        Rate to spawn users at (users per second). Primarily used together with --headless or
                        --autostart
  -t RUN_TIME, --run-time RUN_TIME
                        Stop after the specified amount of time, e.g. (300s, 20m, 3h, 1h30m, etc.). Only used together
                        with --headless or --autostart. Defaults to run forever.
  -l, --list            Show list of possible User classes and exit

Web UI options:
  --web-host WEB_HOST   Host to bind the web interface to. Defaults to '*' (all interfaces)
  --web-port WEB_PORT, -P WEB_PORT
                        Port on which to run web host
  --headless            Disable the web interface, and start the test immediately. Use -u and -t to control user count
                        and run time
  --autostart           Starts the test immediately (without disabling the web UI). Use -u and -t to control user
                        count and run time
  --autoquit AUTOQUIT   Quits Locust entirely, X seconds after the run is finished. Only used together with
                        --autostart. The default is to keep Locust running until you shut it down using CTRL+C
  --web-auth WEB_AUTH   Turn on Basic Auth for the web interface. Should be supplied in the following format:
                        username:password
  --tls-cert TLS_CERT   Optional path to TLS certificate to use to serve over HTTPS
  --tls-key TLS_KEY     Optional path to TLS private key to use to serve over HTTPS

Master options:
  Options for running a Locust Master node when running Locust distributed. A Master node need Worker nodes that connect to it before it can run load tests.

  --master              Set locust to run in distributed mode with this process as master
  --master-bind-host MASTER_BIND_HOST
                        Interfaces (hostname, ip) that locust master should bind to. Only used when running with
                        --master. Defaults to * (all available interfaces).
  --master-bind-port MASTER_BIND_PORT
                        Port that locust master should bind to. Only used when running with --master. Defaults to
                        5557.
  --expect-workers EXPECT_WORKERS
                        How many workers master should expect to connect before starting the test (only when
                        --headless/autostart is used).
  --expect-workers-max-wait EXPECT_WORKERS_MAX_WAIT
                        How long should the master wait for workers to connect before giving up. Defaults to wait
                        forever

Worker options:
  Options for running a Locust Worker node when running Locust distributed.
  Only the LOCUSTFILE (-f option) needs to be specified when starting a Worker, since other options such as -u, -r, -t are specified on the Master node.

  --worker              Set locust to run in distributed mode with this process as worker
  --master-host MASTER_NODE_HOST
                        Host or IP address of locust master for distributed load testing. Only used when running with
                        --worker. Defaults to 127.0.0.1.
  --master-port MASTER_NODE_PORT
                        The port to connect to that is used by the locust master for distributed load testing. Only
                        used when running with --worker. Defaults to 5557.

Tag options:
  Locust tasks can be tagged using the @tag decorator. These options let specify which tasks to include or exclude during a test.

  -T [TAG ...], --tags [TAG ...]
                        List of tags to include in the test, so only tasks with any matching tags will be executed
  -E [TAG ...], --exclude-tags [TAG ...]
                        List of tags to exclude from the test, so only tasks with no matching tags will be executed

Request statistics options:
  --csv CSV_PREFIX      Store current request stats to files in CSV format. Setting this option will generate three
                        files: [CSV_PREFIX]_stats.csv, [CSV_PREFIX]_stats_history.csv and [CSV_PREFIX]_failures.csv
  --csv-full-history    Store each stats entry in CSV format to _stats_history.csv file. You must also specify the '--
                        csv' argument to enable this.
  --print-stats         Print stats in the console
  --only-summary        Only print the summary stats
  --reset-stats         Reset statistics once spawning has been completed. Should be set on both master and workers
                        when running in distributed mode
  --html HTML_FILE      Store HTML report to file path specified

Logging options:
  --skip-log-setup      Disable Locust's logging setup. Instead, the configuration is provided by the Locust test or
                        Python defaults.
  --loglevel LOGLEVEL, -L LOGLEVEL
                        Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL. Default is INFO.
  --logfile LOGFILE     Path to log file. If not set, log will go to stderr

Other options:
  --show-task-ratio     Print table of the User classes' task execution ratio. Use this with non-zero --user option if
                        some classes define non-zero fixed_count property.
  --show-task-ratio-json
                        Print json data of the User classes' task execution ratio. Use this with non-zero --user
                        option if some classes define non-zero fixed_count property.
  --version, -V         Show program's version number and exit
  --exit-code-on-error EXIT_CODE_ON_ERROR
                        Sets the process exit code to use when a test result contain any failure or error
  -s STOP_TIMEOUT, --stop-timeout STOP_TIMEOUT
                        Number of seconds to wait for a simulated user to complete any executing task before exiting.
                        Default is to terminate immediately. This parameter only needs to be specified for the master
                        process when running Locust distributed.
  --equal-weights       Use equally distributed task weights, overriding the weights specified in the locustfile.
  --enable-rebalancing  Allow to automatically rebalance users if new workers are added or removed during a test run.

User classes:
  UserClass             Optionally specify which User classes that should be used (available User classes can be
                        listed with -l or --list)
参数说明
-h, --help    查看帮助
-H HOST, --host=HOST    指定被测试的主机,采用以格式:http://10.21.32.33
--web-host=WEB_HOST    指定运行 Locust Web 页面的主机,默认为空 ''。
-P PORT, --port=PORT, --web-port=PORT    指定 --web-host 的端口,默认是8089
-f LOCUSTFILE, --locustfile=LOCUSTFILE    指定运行 Locust 性能测试文件,默认为: locustfile.py
--csv=CSVFILEBASE, --csv-base-name=CSVFILEBASE    以CSV格式存储当前请求测试数据。
--master    Locust 分布式模式使用,当前节点为 master 节点。
--slave    Locust 分布式模式使用,当前节点为 slave 节点。
--master-host=MASTER_HOST    分布式模式运行,设置 master 节点的主机或 IP 地址,只在与 --slave 节点一起运行时使用,默认为:127.0.0.1.
--master-port=MASTER_PORT    分布式模式运行, 设置 master 节点的端口号,只在与 --slave 节点一起运行时使用,默认为:5557。注意,slave 节点也将连接到这个端口+1 上的 master 节点。
--master-bind-host=MASTER_BIND_HOST    Interfaces (hostname, ip) that locust master should bind to. Only used when running with --master. Defaults to * (all available interfaces).
--master-bind-port=MASTER_BIND_PORT    Port that locust master should bind to. Only used when running with --master. Defaults to 5557. Note that Locust will also use this port + 1, so by default the master node will bind to 5557 and 5558.
--expect-slaves=EXPECT_SLAVES    How many slaves master should expect to connect before starting the test (only when --no-web used).
--no-web    no-web 模式运行测试,需要 -c 和 -r 配合使用.
-c NUM_CLIENTS, --clients=NUM_CLIENTS    指定并发用户数,作用于 --no-web 模式。
-r HATCH_RATE, --hatch-rate=HATCH_RATE    指定每秒启动的用户数,作用于 --no-web 模式。
-t RUN_TIME, --run-time=RUN_TIME    设置运行时间, 例如: (300s, 20m, 3h, 1h30m). 作用于 --no-web 模式。
-L LOGLEVEL, --loglevel=LOGLEVEL    选择 log 级别(DEBUG/INFO/WARNING/ERROR/CRITICAL). 默认是 INFO.
--logfile=LOGFILE    日志文件路径。如果没有设置,日志将去 stdout/stderr
--print-stats    在控制台中打印数据
--only-summary    只打印摘要统计
--no-reset-stats    Do not reset statistics once hatching has been completed。
-l, --list    显示测试类, 配置 -f 参数使用
--show-task-ratio    打印 locust 测试类的任务执行比例,配合 -f 参数使用.
--show-task-ratio-json    以 json 格式打印 locust 测试类的任务执行比例,配合 -f 参数使用.
-V, --version    查看当前 Locust 工具的版本.

 3.Locust组成的库

  • gevent

    gevent是一种基于协程的Python网络库,它用到Greenlet提供的,封装了libevent事件循环的高层同步API。
  • flask

    Python编写的轻量级Web应用框架。
  • requests

    Python Http库
  •  msgpack-python

    MessagePack是一种快速、紧凑的二进制序列化格式,适用于类似JSON的数据格式。msgpack-python主要提供MessagePack数据序列化及反序列化的方法。
  • six

    Python2和3兼容库,用来封装Python2和Python3之间的差异性
  • pyzmq

    pyzmq是zeromq(一种通信队列)的Python绑定,主要用来实现Locust的分布式模式运行

    当我们在安装 Locust 时,它会检测我们当前的 Python 环境是否已经安装了这些库,如果没有安装,它会先把这些库一一装上。

    并且对这些库版本有要求,有些是必须等于某版本,有些是大于某版本。我们也可以事先把这些库全部按要求装好,再安装Locust时就会快上许多。

 4.Locust测试脚本

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# author:特昂糖

from locust import HttpUser, task, between

class QuickStartUser(HttpUser):
    '''定义模拟用户'''
    wait_time = between(1, 2.5) #两次请求间隔时间设置在1-2.5间

    @task
    def login(self):
        r=self.client.post(url="/login/auth/",
                           headers={"content-type":"application/json"},
                           json={
                               "username":"15227132986",
                               "password":"******"})
        assert r.status_code == 200

   Locust函数详解:

    1.  on_start()  :每个并发用户在开始前各执行一次
    2. on_stop():每个并发用户在结束后各执行一次
    3. @task: 通过装饰器设置运行权重,比如上面代码中 执行任务 home_index 和 sale 的总请求为 2:1
    4. assert:断言设置  
    5. wait_time :每个任务之间设置间隔时间,随机从3~5区间内取,单位是 s  
    6. locust -f:指定 .py 压测脚本路径  

 5.Locust启动监控

  • cmd进入控制台

  • 到Python文件所在路径

  • 执行命令

    命令参数详解
    
    -f:要导入的Python模块:
    -H:要测试的服务器地址;
    -c, --clients:指定并发用户数; -n, --num-request:指定总执行测试次数; -r, --hatch-rate:指定并发加压速率,默认值位1。
    示例:    locust
    -f locustfile.py -H http://**.95.**.233:8**0

    [2022-02-17 17:27:04,394] LAPTOP-JFOHHCS8/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
    [2022-02-17 17:27:04,410] LAPTOP-JFOHHCS8/INFO/locust.main: Starting Locust 2.8.2
  • 运行结果

    启动完毕后,就可以在浏览器中通过http://localhost:8089进入Locust的Web管理页面了
    • Locust页面设置详解:

      • Number of total users to simulate:>>>设置模拟的?户总数

      • Spawn rate (users spawned/second):>>>每秒启动的?户虚拟数

      • Host (e.g. http://www.example.com):>>>被测的?标服务器的地址信息

 6.Locust监控页面

参数详解:
Type:请求类型(也就是请求具体是那个=?法) Name:请求的路径地址信息 Requests:当前已完成的请求数量 Fails:当前失败的数量 Mediam(ms): 响应时间的中位数 90%ile (ms):90%的请求响应时间 Average (ms):平均响应时间 Min (ms):最?响应时间 Max (ms):最?响应时间 Average size (bytes):平均请求的数据量 Current RPS:每秒中处理请求的数量,也就是RPS

菜单栏:
New test:点击该按钮可对模拟的总虚拟?户数和每秒启动的虚拟?户数进?编辑;
Statistics:聚合报告
Charts:测试结果变化趋势的曲线展示图,分别为每秒完成的请求数(RPS)、响应时间、不同时间的虚拟?户数;
Failures:失败请求的展示界?;
Exceptions:异常请求的展示界?;
Download Data:测试数据下载模块, 提供三种类型的CSV格式的下载,分别是:Statistics、responsetime、
exceptions;