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  

一般来说,上面几行命令够用了。
posted @ 2020-04-28 15:23  walkerpython  阅读(191)  评论(0编辑  收藏  举报