• locust描述


    LoadRunner 和 Jmeter 这类采用进程和线程的测试工具,都很难在单机上模拟出较高的并发压力。Locust 的并发机制摒弃了进程和线程,采用协程(gevent)的机制。协程避免了系统级资源调度,由此可以大幅提高单机的并发能力。

    官网url  https://docs.locust.io/en/stable/installation.html

    1 安装 python3 -m pip install locustio

    locust --help  通过 help 检查是否安装成功

    • gevent 是在 Python 中实现协程的一个第三方库。协程,又称微线程(Coroutine)。使用 gevent 可以获得极高的并发性能。

    深入浅出开源性能测试工具 Locust(使用篇)

    https://debugtalk.com/post/head-first-locust-user-guide/

      1在Locust测试框架中,测试场景是采用纯Python脚本进行描述的。对于最常见的HTTP(S)协议的系统,Locust采用Python的requests库作为客户端,使得脚本编写大大简化,富有表现力的同时且极具美感。而对于其它协议类型的系统,Locust也提供了接口,只要我们能采用Python编写对应的请求客户端,就能方便地采用Locust实现压力测试。从这个角度来说,Locust可以用于压测任意类型的系统

    2 在模拟有效并发方面,Locust的优势在于其摒弃了进程和线程,完全基于事件驱动,使用gevent提供的非阻塞IOcoroutine来实现网络层的并发请求,因此即使是单台压力机也能产生数千并发请求数;

    3

     

    然后再来看参数化这一项。这一项极其普遍,主要是用在测试数据方面。但通过归纳,发现其实也可以概括为三种类型。

    • 循环取数据,数据可重复使用:e.g. 模拟3用户并发请求网页,总共有100个URL地址,每个虚拟用户都会依次循环加载这100个URL地址;
    • 保证并发测试数据唯一性,不循环取数据:e.g. 模拟3用户并发注册账号,总共有90个账号,要求注册账号不重复,注册完毕后结束测试;
    • 保证并发测试数据唯一性,循环取数据:模拟3用户并发登录账号,总共有90个账号,要求并发登录账号不相同,但数据可循环使用。

    5     当并发压力要求较高时,就需要用到Locust的多进程分布式运行模式。从字面意思上看,大家可能第一反应就是多台压力机同时运行,每台压力机分担负载一部分的压力生成。的确,Locust支持任意多台压力机(一主多从(多个cmd中开启slave))的分布式运行模式,但这里说到的多进程分布式运行模式还有另外一种情况,就是在同一台压力机上开启多个slave的情况。这是因为当前阶段大多数计算机的CPU都是多处理器(multiple processor cores),单进程运行模式下只能用到一个处理器的能力,而通过在一台压力机上运行多个slave,就能调用多个处理器的能力了。比较好的做法是,如果一台压力机有N个处理器内核,那么就在这台压力机上启动一个masterNslave。当然,我们也可以启动N的倍数个slave,但是根据我的试验数据,效果跟N个差不多,因此只需要启动Nslave即可。

    6

    如果采用no_web形式,则需使用--no-web参数,并会用到如下几个参数。

    • -c, --clients:指定并发用户数;
    • -r, --hatch-rate:指定并发加压速率,默认值位1

    7

    Locust的Web管理页面中,需要配置的参数只有两个:

    • Number of users to simulate: 设置并发用户数,对应中no_web模式的-c, --clients参数;
    • Hatch rate (users spawned/second): 启动虚拟用户的速率,对应着no_web模式的-r, --hatch-rate参数

    多进程分布式运行

    不管是单机多进程,还是多机负载模式,运行方式都是一样的,都是先运行一个master,再启动多个slave

    9

    10

    循环取数据,数据可重复使用

    所有并发虚拟用户共享同一份测试数据,各虚拟用户在数据列表中循环取值
    例如,模拟3用户并发请求网页,总共有100个URL地址,每个虚拟用户都会依次循环加载这100个URL地址;加载示例如下表所示。

    from locust import TaskSet, task, HttpLocust

    class UserBehavior(TaskSet):
    def on_start(self):
    self.index = 0

    @task
    def test_visit(self):
    url = self.locust.share_data[self.index]
    print('visit url: %s' % url)
    self.index = (self.index + 1) % len(self.locust.share_data)
    self.client.get(url)

    class WebsiteUser(HttpLocust):
    host = 'https://debugtalk.com'
    task_set = UserBehavior
    share_data = ['url1', 'url2', 'url3', 'url4', 'url5']
    min_wait = 1000
    max_wait = 3000



    11

    保证并发测试数据唯一性,不循环取数据

    所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复。
    例如,模拟3用户并发注册账号,总共有9个账号,要求注册账号不重复,注册完毕后结束测试;加载示例如下表所示。

    from locust import TaskSet, task, HttpLocust
    import queue

    class UserBehavior(TaskSet):

    @task
    def test_register(self):
    try:
    data = self.locust.user_data_queue.get()
    except queue.Empty:
    print('account data run out, test ended.')
    exit(0)

    print('register with user: {}, pwd: {}'
    .format(data['username'], data['password']))
    payload = {
    'username': data['username'],
    'password': data['password']
    }
    self.client.post('/register', data=payload)

    class WebsiteUser(HttpLocust):
    host = 'https://debugtalk.com'
    task_set = UserBehavior

    user_data_queue = queue.Queue()
    for index in range(100):
    data = {
    "username": "test%04d" % index,
    "password": "pwd%04d" % index,
    "email": "test%04d@debugtalk.test" % index,
    "phone": "186%08d" % index,
    }
    user_data_queue.put_nowait(data)

    min_wait = 1000
    max_wait = 3000


    12

    保证并发测试数据唯一性,循环取数据

    所有并发虚拟用户共享同一份测试数据,保证并发虚拟用户使用的数据不重复,并且数据可循环重复使用。
    例如,模拟3用户并发登录账号,总共有9个账号,要求并发登录账号不相同,但数据可循环使用;加载示例如下表所示


    该种场景的实现方式与上一种场景基本相同,唯一的差异在于,每次使用完数据后,需要再将数据放入队列中。
    from locust import TaskSet, task, HttpLocust
    import queue

    class UserBehavior(TaskSet):

    @task
    def test_register(self):
    try:
    data = self.locust.user_data_queue.get()
    except queue.Empty:
    print('account data run out, test ended.')
    exit(0)

    print('register with user: {}, pwd: {}'
    .format(data['username'], data['password']))
    payload = {
    'username': data['username'],
    'password': data['password']
    }
    self.client.post('/register', data=payload)
    self.locust.user_data_queue.put_nowait(data)

    class WebsiteUser(HttpLocust):
    host = 'https://debugtalk.com'
    task_set = UserBehavior

    user_data_queue = queue.Queue()
    for index in range(100):
    data = {
    "username": "test%04d" % index,
    "password": "pwd%04d" % index,
    "email": "test%04d@debugtalk.test" % index,
    "phone": "186%08d" % index,
    }
    user_data_queue.put_nowait(data)

    min_wait = 1000
    max_wait = 3000

    locust --help Usage: locust [options] [LocustClass [LocustClass2 ... ]] Options: -h, --help show this help message and exit -H HOST, --host=HOST Host to load test in the following format: 被测系统的host,若在Terminal中不进行指定,就需要在Locust子类中通过host参数进行指定 http://10.21.32.33 --web-host=WEB_HOST Host to bind the web interface to. Defaults to '' (all interfaces) -P PORT, --port=PORT, --web-port=PORT Port on which to run web host -f LOCUSTFILE, --locustfile=LOCUSTFILE 指定执行的Locust脚本文件 Python module file to import, e.g. '../other.py'. Default: locustfile --csv=CSVFILEBASE, --csv-base-name=CSVFILEBASE Store current request stats to files in CSV format. --master Set locust to run in distributed mode with this process as master --slave Set locust to run in distributed mode with this process as slave --master-host=MASTER_HOST Host or IP address of locust master for distributed load testing. Only used when running with --slave. Defaults to 127.0.0.1. --master-port=MASTER_PORT The port to connect to that is used by the locust master for distributed load testing. Only used when running with --slave. Defaults to 5557. Note that slaves will also connect to the master node on this port + 1. --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 Disable the web interface, and instead start running the test immediately. Requires -c and -r to be specified. -c NUM_CLIENTS, --clients=NUM_CLIENTS Number of concurrent Locust users. Only used together with --no-web -r HATCH_RATE, --hatch-rate=HATCH_RATE The rate per second in which clients are spawned. Only used together with --no-web -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 --no- web -L LOGLEVEL, --loglevel=LOGLEVEL Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL. Default is INFO. --logfile=LOGFILE Path to log file. If not set, log will go to stdout/stderr --print-stats Print stats in the console --only-summary Only print the summary stats --no-reset-stats Do not reset statistics once hatching has been completed -l, --list Show list of possible locust classes and exit --show-task-ratio print table of the locust classes' task execution ratio --show-task-ratio-json print json data of the locust classes' task execution ratio -V, --version show program's version number and exit


    -h: 查看帮助
    
    -H: 被测服务器的域名。
        如果想启动的时候,不加“-H”参数,那么在启动脚本里面的就要加上 host="http://sample",写在HttpLocust子类里面。
        脚本里面写 get或post请求 的时候,url只写路径例如 “/login”。
    
    --web-host:locust服务的web界面,用于配置 并发量 与 启动量。在web界面可以实时查看压测结果。
                (如果是分布式,用于master,不用于slave)(理解的可能不对)
    
    --master: 做分布式压测时,标记哪台用做主机。
               主机只用来做统计,并不用来施压。施压的任务留给slave分机做。如果想主机也做来施压,就要在主机上也启动一个slave。
    
    --slave:做分布式压测时,标记哪些用做分机。分机的主要任务是进行施压。
    
    -f:脚本路径。可以写相对路径或是绝对路径。如果是脚本当前目录下,就写相对路径。如果不是,就写绝地路径。
    
    --master-host: 做分布式压测时,指定主机的IP。只用于slave。如果没有指定,默认是本机“127.0.0.1”。
    
    --master-port: 做分布式压测时,指定主机的port。只用于slave。如果没有指定且主机没有修改的话,默认是5557。
    
    --master-bind-host: 做分布式压测时,指定分机IP。只用于master。如果没有指定,默认是所有可用的IP(即所有标记主机IP的slave)
    
    --master-bind-port:做分布式压测时,指定分机port。默认是5557与5558。
    
    --no-web:不带web界面。使用这个参数时,必须指定 -c、-r。
    
    -c: 用户数。
    -r: 每秒启动用户数。
    -t: 运行时长。在t秒后停止。
    -L:打印的日志级别,默认INFO。
    
    --logfile:同-f
    -V:查看Locust版本。
    --host:同-H
    
    PS: 如果参数是以“--”开头,则以=连接实参。例如“--host=http://sample”。如果不是,则以空格连接实参。例如“-H http://sample”
    
    以下是常用的组合:
    
    单机压测:
    locust -f filepath  # 脚本指定host
    locust -f filepath -H http://sample  # 脚本未指定host
    
    分布压测假定脚本指定host:
    master: 
    locust -f filepath --master
    slave:
    locust -f filepath --slave --master-host=192.168.2.221  
    
    一般来说,上面几行命令够用了。
  • 相关阅读:
    进程空间与系统空间(一)
    内核之最
    Linux 内核3.10.5 专场
    device_create与device_register
    重写与重载的含义
    抽象类和接口的区别
    Spring知识点
    mybatis学习
    知识点
    Mybatis面试题
  • 原文地址:https://www.cnblogs.com/pythonwork/p/12794554.html
Copyright © 2020-2023  润新知