内容来自网络html
https://www.w3xue.com/exp/article/20191/16707.htmlnode
https://blog.csdn.net/qq_36255988/article/details/82622044python
1、Locust描述nginx
(1)git
优势:github
1. 易用。很方便地基于Python进行脚本扩展和业务请求实现。golang
2. 彻底基于事件驱动,因此不受进程和线程的限制,能够支持发起更高的并发数请求。web
3. 能够分布式发起并发请求算法
4.Locust有一个整洁的HTML+JS的用户界面,实时显示相关测试细节。因为用户界面是基于网络的,它是跨平台的和容易扩展。json
5. 开源。
缺点:
1. 图表相对loadrunner 比较简单。(在Linux 下部署时能够看到图表,在Windows 下没有)
2. 不支持监控被测机,须要结合nmon等工具辅助监控。
2、Locust安装
1.一、 ---> pip3 install locust
1.2 、 经过GitHub上克隆项目安装(Python3推荐):https://github.com/locustio/locust ,而后执行 ...\locust> python setup.py install
二、安装 pyzmq
If you intend to run Locust distributed across multiple processes/machines, we recommend you to also install pyzmq.
若是打算运行Locust 分布在多个进程/机器,须要安装pyzmq.
经过pip命令安装。 /> pip install pyzmq
三、安装成功,CMD敲入命令验证。 /> locust --help
1 Options: 2 -h, --help show this help message and exit 3 -H HOST, --host=HOST Host to load test in the following format: 4 http://10.21.32.33 5 --web-host=WEB_HOST Host to bind the web interface to. Defaults to '' (all 6 interfaces) 7 -P PORT, --port=PORT, --web-port=PORT 8 Port on which to run web host 9 -f LOCUSTFILE, --locustfile=LOCUSTFILE 10 Python module file to import, e.g. '../other.py'. 11 Default: locustfile 12 --csv=CSVFILEBASE, --csv-base-name=CSVFILEBASE 13 Store current request stats to files in CSV format. 14 --master Set locust to run in distributed mode with this 15 process as master 16 --slave Set locust to run in distributed mode with this 17 process as slave 18 --master-host=MASTER_HOST 19 Host or IP address of locust master for distributed 20 load testing. Only used when running with --slave. 21 Defaults to 127.0.0.1. 22 --master-port=MASTER_PORT 23 The port to connect to that is used by the locust 24 master for distributed load testing. Only used when 25 running with --slave. Defaults to 5557. Note that 26 slaves will also connect to the master node on this 27 port + 1. 28 --master-bind-host=MASTER_BIND_HOST 29 Interfaces (hostname, ip) that locust master should 30 bind to. Only used when running with --master. 31 Defaults to * (all available interfaces). 32 --master-bind-port=MASTER_BIND_PORT 33 Port that locust master should bind to. Only used when 34 running with --master. Defaults to 5557. Note that 35 Locust will also use this port + 1, so by default the 36 master node will bind to 5557 and 5558. 37 --heartbeat-liveness=HEARTBEAT_LIVENESS 38 set number of seconds before failed heartbeat from 39 slave 40 --heartbeat-interval=HEARTBEAT_INTERVAL 41 set number of seconds delay between slave heartbeats 42 to master 43 --expect-slaves=EXPECT_SLAVES 44 How many slaves master should expect to connect before 45 starting the test (only when --no-web used). 46 --no-web Disable the web interface, and instead start running 47 the test immediately. Requires -c and -r to be 48 specified. 49 -c NUM_CLIENTS, --clients=NUM_CLIENTS 50 Number of concurrent Locust users. Only used together 51 with --no-web 52 -r HATCH_RATE, --hatch-rate=HATCH_RATE 53 The rate per second in which clients are spawned. Only 54 used together with --no-web 55 -t RUN_TIME, --run-time=RUN_TIME 56 Stop after the specified amount of time, e.g. (300s, 57 20m, 3h, 1h30m, etc.). Only used together with --no- 58 web 59 -L LOGLEVEL, --loglevel=LOGLEVEL 60 Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL. 61 Default is INFO. 62 --logfile=LOGFILE Path to log file. If not set, log will go to 63 stdout/stderr 64 --print-stats Print stats in the console 65 --only-summary Only print the summary stats 66 --no-reset-stats [DEPRECATED] Do not reset statistics once hatching has 67 been completed. This is now the default behavior. See 68 --reset-stats to disable 69 --reset-stats Reset statistics once hatching has been completed. 70 Should be set on both master and slaves when running 71 in distributed mode 72 -l, --list Show list of possible locust classes and exit 73 --show-task-ratio print table of the locust classes' task execution 74 ratio 75 --show-task-ratio-json 76 print json data of the locust classes' task execution 77 ratio 78 -V, --version show program's version number and exit
参数说明:
四、Locust主要由下面的几个库构成:
1) gevent
gevent是一种基于协程的Python网络库,它用到Greenlet提供的,封装了libevent事件循环的高层同步API。
2) flask
Python编写的轻量级Web应用框架。
3) requests
Python Http库
4) msgpack-python
MessagePack是一种快速、紧凑的二进制序列化格式,适用于相似JSON的数据格式。msgpack-python主要提供MessagePack数据序列化及反序列化的方法。
5) six
Python2和3兼容库,用来封装Python2和Python3之间的差别性
6) pyzmq
pyzmq是zeromq(一种通讯队列)的Python绑定,主要用来实现Locust的分布式模式运行
当咱们在安装 Locust 时,它会检测咱们当前的 Python 环境是否已经安装了这些库,若是没有安装,它会先把这些库一一装上。而且对这些库版本有要求,有些是必须等于某版本,有些是大于某版本。咱们也能够事先把这些库所有按要求装好,再安装Locust时就会快上许多。
3、编写接口压测脚本文件locustfile.py
脚本模板(参考)
1 from locust import HttpLocust, TaskSet, task 2 3 class UserBehavior(TaskSet): 4 def setup(self): 5 print('task setup') 6 7 def teardown(self): 8 print('task teardown') 9 10 def on_start(self): 11 # 虚拟用户启动Task时运行 12 print('start') 13 14 def on_stop(self): 15 # 虚拟用户结束Task时运行 16 print('end') 17 18 @task(2) 19 def index(self): 20 self.client.get("/") 21 22 @task(1) 23 def profile(self): 24 self.client.get("/profile") 25 26 class WebsiteUser(HttpLocust): 27 def setup(self): 28 print('locust setup') 29 30 def teardown(self): 31 print('locust teardown') 32 33 host = http: // XXXXX.com 34 task_set = UserBehavior 35 min_wait = 5000 36 max_wait = 9000 37 38 if __name__ == '__main__': 39 pass
说明:
Locust类有setup和teardown,TaskSet类有setup、teardown、on_start、on_stop。
每次启动locust时运行setup方法,退出时运行teardown方法,locust执行TaskSet时运行TaskSet的setup方法,退出时运行teardown方法,每一个虚拟用户执行操做时运行on_start方法,退出时执行on_stop方法,运行上面的脚本,执行顺序以下:
执行顺序:Locust setup → TaskSet setup → TaskSet on_start → TaskSet tasks → TaskSet on_stop → TaskSet teardown → Locust teardown
举个脚本栗子
1 from locust import HttpLocust, TaskSet, task 2 3 4 class ScriptTasks(TaskSet): 5 def on_start(self): 6 self.client.post("/login", { 7 "username": "test", 8 "password": "123456" 9 }) 10 11 @task(2) 12 def index(self): 13 self.client.get("/") 14 15 @task(1) 16 def about(self): 17 self.client.get("/about/") 18 19 @task(1) 20 def demo(self): 21 payload = {} 22 headers = {} 23 self.client.post("/demo/", data=payload, headers=headers) 24 25 26 class WebsiteUser(HttpLocust): 27 task_set = ScriptTasks 28 host = "http://example.com" 29 min_wait = 1000 30 max_wait = 5000
脚本解读:
脚本使用场景解读:
一、在这个示例中,定义了针对http://example.com
网站的测试场景:先模拟用户登陆系统,而后随机地访问首页(/
)和关于页面(/about/
),请求比例为2:1,
demo方法主要用来阐述client对post接口的处理方式;而且,在测试过程当中,两次请求的间隔时间为1->
5
秒间的随机值。
二、从脚本中能够看出,脚本主要包含两个类(类名可自定义),一个是WebsiteUser
(继承自HttpLocust
,而HttpLocust
继承自Locust
),另外一个是ScriptTasks
(继承自TaskSet
)。事实上,在Locust
的测试脚本中,全部业务测试场景都是在Locust
和TaskSet
两个类的继承子类中进行描的。
三、那如何理解Locust
和TaskSet
这两个类呢?简单地说,Locust类
就比如是一群蝗虫,而每一只蝗虫就是一个类的实例。相应的,TaskSet类
就比如是蝗虫的大脑,控制着蝗虫的具体行为,即实际业务场景测试对应的任务集。
4、Locust类
实例脚本
伪代码:
1 from locust import HttpLocust, TaskSet, task 2 3 4 class WebsiteTasks(TaskSet): 5 def on_start(self): # 进行初始化的工做,每一个Locust用户开始作的第一件事 6 payload = { 7 "username": "test_user", 8 "password": "123456", 9 } 10 header = { 11 "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" 12 } 13 self.client.post("/login", data=payload,headers=header) 14 # self.client属性使用Python request库的全部方法,调用和使用方法和requests彻底一致; 15 16 @task(5) 17 # 经过@task()装饰的方法为一个事务,方法的参数用于指定该行为的执行权重,参数越大每次被虚拟用户执行的几率越高,默认为1 18 def index(self): 19 self.client.get("/") 20 21 @task(1) 22 def about(self): 23 self.client.get("/about/") 24 25 26 class WebsiteUser(HttpLocust): 27 host = "https://github.com/" # 被测系统的host,在终端中启动locust时没有指定--host参数时才会用到 28 task_set = WebsiteTasks # TaskSet类,该类定义用户任务信息,必填。这里就是:WebsiteTasks类名,由于该类继承TaskSet; 29 min_wait = 5000 # 每一个用户执行两个任务间隔时间的上下限(毫秒),具体数值在上下限中随机取值,若不指定默认间隔时间固定为1秒 30 max_wait = 15000
伪代码中对https://github.com/网站的测试场景,先模拟用户登陆系统,而后随机访问首页/和/about/,请求比例5:1,而且在测试过程当中,两次请求的间隔时间1-5秒的随机值;
on_start方法,在正式执行测试前执行一次,主要用于完成一些初始化的工做,例如登陆操做;
WebsiteTasks类中如何去调用 WebsiteUser(HttpLocust)类中定义的字段和方法呢?
经过在WebsiteTasks类中self.locust.xxoo xxoo就是咱们在WebsiteUser类中定义的字段或方法;
伪代码:
1 from locust import HttpLocust, TaskSet, task 2 import hashlib 3 import Queue 4 5 6 class WebsiteTasks(TaskSet): 7 @task(5) 8 def index(self): 9 data = self.locust.user_data_queue # 获取WebsiteUser里面定义的ser_data_queue队列 10 md5_data = self.locust.md5_encryption() # 获取WebsiteUser里面定义的md5_encryption()方法 11 self.client.get("/") 12 13 14 class WebsiteUser(HttpLocust): 15 host = "https://github.com/" 16 task_set = WebsiteTasks 17 min_wait = 5000 18 max_wait = 15000 19 user_data_queue = Queue.Queue() 20 21 def md5_encryption(self, star): 22 '''md5加密方法''' 23 obj = hashlib.md5() 24 obj.update(bytes(star, encoding="utf-8")) 25 result = obj.hexdigest() 26 return result
伪代码中测试场景如何表达?
代码主要包含两个类:
在Locust测试脚本中,全部业务测试场景都是在Locust和TaskSet两个类的继承子类中进行描述;
简单说:Locust类就相似一群蝗虫,而每只蝗虫就是一个类的实例。TaskSet类就相似蝗虫的大脑,控制蝗虫的具体行为,即实际业务场景测试对应的任务集;
源码中:class Locust(object)和class HttpLocust(Locust) 此处可查看源代码
在Locust类中,静态字段client即客户端的请求方法,这里的client字段没有绑定客户端请求方法,所以在使用Locust时,须要先继承Locust类class HttpLocust(Locust),而后在self.client =HttpSession(base_url=self.host)绑定客户端请求方法;
对于常见的HTTP(s)协议,Locust已经实现了HttpLocust类,其self.client=HttpSession(base_url=self.host),而HttpSession继承自requests.Session。所以在测试HTTP(s)的Locust脚本中,能够经过client属性来使用Python requests库的所 有方法,调用方式与 reqeusts彻底一致。另外,因为requests.Session的使用,client的方法调用之间就自动具备了状态记忆功能。常见的场景就是,在登陆系统后能够维持登陆状态的Session,从然后续HTTP请求操做都能带上登陆状态;
Locust类中,除了client属性,还有几个属性须要关注:
Locust流程,测试开始后,每一个虚拟用户(Locust实例)运行逻辑都会遵照以下规律:
class TaskSet
TaskSet类实现了虚拟用户所执行任务的调度算法,包括规划任务执行顺序(schedule_task)、挑选下一个任务(execute_next_task)、执行任务(execute_task)、休眠等待(wait)、中断控制(interrupt)等待。在此基础上,就能够在TaskSet子类中采用很是简洁的方式来描述虚拟用户的业务测试场景,对虚拟用户的全部行为进行组织和描述,并能够对不一样任务的权重进行配置。
@task
经过@task()装饰的方法为一个事务。方法的参数用于指定该行为的执行权重。参数越大每次被虚拟用户执行的几率越高。若是不设置默认为1。
TaskSet子类中定义任务信息时,采起两种方式:@task装饰器和tasks属性。
采用@task装饰器定义任务信息时:
1 from locust import TaskSet, task 2 3 class UserBehavior(TaskSet): 4 @task(1) 5 def test_job1(self): 6 self.client.get('/test1') 7 8 @task(3) 9 def test_job2(self): 10 self.client.get('/test2')
采用tasks属性定义任务信息时
1 from locust import TaskSet 2 3 def test_job1(obj): 4 obj.client.get('/test1') 5 6 def test_job2(obj): 7 obj.client.get('/test2') 8 9 class UserBehavior(TaskSet): 10 tasks = {test_job1: 1, test_job2: 2} 11 # tasks = [(test_job1,1), (test_job1,3)] # 两种方式等价
上面两种定义任务信息方式中,均设置了权重属性,即执行test_job2的频率是test_job1的两倍。若不指定,默认比例为1:1。
高级用法:
关联
在某些请求中,须要携带以前response中提取的参数,常见场景就是session_id。Python中可用经过re正则匹配,对于返回的html页面,可用采用lxml库来定位获取须要的参数;
1 from locust import HttpLocust, TaskSet, task 2 from lxml import etree 3 4 class WebsiteTasks(TaskSet): 5 def get_session(self, html): # 关联例子 6 tages = etree.HTML(html) 7 return tages.xpath("//div[@class='btnbox']/input[@name='session']/@value")[0] 8 9 def on_start(self): 10 html = self.client.get('/index') 11 session = self.get_session(html.text) 12 payload = { 13 "username": "test_user", 14 "password": "123456", 15 'session': session 16 } 17 header = { 18 "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"19 } 20 self.client.post("/login", data=payload, headers=header) 21 22 @task(5) 23 def index(self): 24 self.client.get("/") 25 assert response['ErrorCode'] == 0 # 断言 26 27 @task(1) 28 def about(self): 29 self.client.get("/about/") 30 31 class WebsiteUser(HttpLocust): 32 host = "https://github.com/" 33 task_set = WebsiteTasks 34 min_wait = 5000 35 max_wait = 15000
参数化
做用:循环取数据,数据可重复使用
例如:模拟3个用户并发请求网页,共有100个URL地址,每一个虚拟用户都会依次循环加载100个URL地址
1 from locust import TaskSet, task, HttpLocust 2 3 class UserBehavior(TaskSet): 4 def on_start(self): 5 self.index = 0 6 7 @task 8 def test_visit(self): 9 url = self.locust.share_data[self.index] 10 print('visit url: %s' % url) 11 self.index = (self.index + 1) % len(self.locust.share_data) 12 self.client.get(url) 13 14 class WebsiteUser(HttpLocust): 15 host = 'http://debugtalk.com' 16 task_set = UserBehavior 17 share_data = ['url1', 'url2', 'url3', 'url4', 'url5'] 18 min_wait = 1000 19 max_wait = 3000
保证并发测试数据惟一性,不循环取数据;
全部并发虚拟用户共享同一份测试数据,而且保证虚拟用户使用的数据不重复;
例如:模拟3用户并发注册帐号,共有9个帐号,要求注册帐号不重复,注册完毕后结束测试:
采用队列
1 from locust import TaskSet, task, HttpLocust 2 import Queue 3 4 class UserBehavior(TaskSet): 5 @task 6 def test_register(self): 7 try: 8 data = self.locust.user_data_queue.get() 9 except Queue.Empty: 10 print('account data run out, test ended.') 11 exit(0) 12 print('register with user: {}, pwd: {}'.format(data['username'], data['password'])) 13 payload = { 14 'username': data['username'], 15 'password': data['password'] 16 } 17 self.client.post('/register', data=payload) 18 19 class WebsiteUser(HttpLocust): 20 host = 'http://XXXXX.com' 21 task_set = UserBehavior 22 user_data_queue = Queue.Queue() 23 for index in range(100): 24 data = { 25 "username": "test%04d" % index, 26 "password": "pwd%04d" % index, 27 "email": "test%04d@debugtalk.test" % index, 28 "phone": "186%08d" % index, 29 } 30 user_data_queue.put_nowait(data) 31 min_wait = 1000 32 max_wait = 3000
保证并发测试数据惟一性,循环取数据;
全部并发虚拟用户共享同一份测试数据,保证并发虚拟用户使用的数据不重复,而且数据可循环重复使用;
例如:模拟3个用户并发登陆帐号,总共有9个帐号,要求并发登陆帐号不相同,但数据可循环使用;
1 class UserBehavior(TaskSet): 2 @task 3 def test_register(self): 4 try: 5 data = self.locust.user_data_queue.get() 6 except Queue.Empty: 7 print('account data run out, test ended') 8 exit(0) 9 print('register with user: {0}, pwd: {1}'.format(data['username'], data['password'])) 10 payload = { 11 'username': data['username'], 12 'password': data['password'] 13 } 14 self.client.post('/register', data=payload) 15 self.locust.user_data_queue.put_nowait(data) 16 17 class WebsiteUser(HttpLocust): 18 host = 'http://XXXXXX.com' 19 task_set = UserBehavior 20 user_data_queue = Queue.Queue() 21 for index in range(100): 22 data = { 23 "username": "test%04d" % index, 24 "password": "pwd%04d" % index, 25 "email": "test%04d@debugtalk.test" % index, 26 "phone": "186%08d" % index, 27 } 28 user_data_queue.put_nowait(data) 29 min_wait = 1000 30 max_wait = 3000
断言(即检查点)
性能测试也须要设置断言么? 某些状况下是须要,好比你在请求一个页面时,就能够经过状态来判断返回的 HTTP 状态码是否是 200。
经过with self.client.get("url地址",catch_response=True) as response的形式;
response.status_code获取http响应码进行判断,失败后会加到统计错误表中;
python自带的断言assert失败后代码就不会向下走,且失败后不会被Locust报表统计进去;
默认不写参数catch_response=False断言无效,将catch_response=True才生效;
下面例子中:
首先使用python断言对接口返回值进行判断(python断言不经过,代码就不向下执行,get请求数为0),经过后对该接口的http响应是否为200进行判断;
1 @task 2 def all_interface(self): 3 # 豆瓣图书api为例子 4 with self.client.get("https://api.douban.com/v2/book/1220562", name="/LhcActivity/GetActConfig", 5 catch_response=True) as response: 6 assert response.json()['rating']['max'] == 10 # python断言对接口返回值中的max字段进行断言 7 if response.status_code == 200: # 对http响应码是否200进行判断 8 response.success() 9 else: 10 response.failure("GetActConfig[Failed!]")
运行Locust
时,一般会使用到两种运行模式:单进程运行和多进程分布式运行。
Locust
全部的虚拟并发用户均运行在单个Python
进程中,具体从使用形式上,又分为no_web
和web
两种形式。该种模式因为单进程的缘由,并不能彻底发挥压力机全部处理器的能力,所以主要用于调试脚本和小并发压测的状况。
当并发压力要求较高时,就须要用到Locust
的多进程分布式运行模式。从字面意思上看,你们可能第一反应就是多台压力机同时运行,每台压力机分担负载一部分的压力生成。的确,Locust
支持任意多台压力机(一主多从)的分布式运行模式,但这里说到的多进程分布式运行模式还有另一种状况,就是在同一台压力机上开启多个slave
的状况。这是由于当前阶段大多数计算机的CPU都是多处理器(multiple processor cores
),单进程运行模式下只能用到一个处理器的能力,而经过在一台压力机上运行多个slave
,就能调用多个处理器的能力了。比较好的作法是,若是一台压力机有N
个处理器内核,那么就在这台压力机上启动一个master
,N
个slave
。固然,咱们也能够启动N
的倍数个slave
,可是根据个人试验数据,效果跟N
个差很少,所以只须要启动N
个slave
便可。
若是采用no_web
形式,则需使用--no-web
参数,并会用到以下几个参数。
-c, --clients
:指定并发用户数;-r, --hatch-rate
:指定并发加压速率,默认值位1。示例:
$ locust -f locustfile.py --host = xxxxx.com --no-web -c 2 -r 1
在此基础上,当咱们想要调试Locust
脚本时,就能够在脚本中须要调试的地方经过print
打印日志,而后将并发数和总执行次数都指定为1
$ locust -f locustfile.py --host = xxxxx.com --no-web -c 1 -r 1
执行测试
经过这种方式,咱们就能很方便地对Locust
脚本进行调试了。
Locust
脚本调试经过后,就算是完成了全部准备工做,能够开始进行压力测试了。
web形式启动locust:
若是采用web
形式,,则一般状况下无需指定其它额外参数,Locust
默认采用8089
端口启动web
;若是要使用其它端口,就可使用以下参数进行指定。
-P, --port
:指定web端口,默认为8089
.Locust
运行在本机,在浏览器中访问http://localhost:8089
便可进入Locust
的Web管理页面;若是Locust
运行在其它机器上,那么在浏览器中访问http://locust_machine_ip:8089
便可。多进程分布式运行
无论是单机多进程
,仍是多机负载
模式,运行方式都是同样的,都是先运行一个master
,再启动多个slave
。
启动master
时,须要使用--master
参数;一样的,若是要使用8089
之外的端口,还须要使用-P, --port
参数。
启动
启动后,还须要启动slave
时须要使用--slave
参数;在slave
中,就不须要再指定端口了。masterslave
才能执行测试任务。
master
和slave
都启动完毕后,就能够在浏览器中经过http://locust_machine_ip:8089
进入Locust
的Web管理页面了。使用方式跟单进程web
形式彻底相同,只是此时是经过多进程负载来生成并发压力,在web
管理界面中也能看到实际的slave
数量。若是slave
与master
不在同一台机器上,还须要经过--master-host
参数再指定master
的IP地址。
运行结果:
Number of users to simulate 设置虚拟用户数,对应中no_web
模式的-c, --clients
参数;
Hatch rate(users spawned/second)每秒产生(启动)的虚拟用户数 , 对应着no_web
模式的-r, --hatch-rate
参数,默认为1。点击Start swarming 按钮,开始运行性能测试。
上图:启动了一个 master 和两个 slave,由两个 slave 来向被测试系统发送请求
性能测试参数
Type: 请求的类型,例如GET/POST。
Name:请求的路径。这里为百度首页,即:https://www.baidu.com/
request:当前请求的数量。
fails:当前请求失败的数量。
Median:中间值,单位毫秒,一半的服务器响应时间低于该值,而另外一半高于该值。
Average:平均值,单位毫秒,全部请求的平均响应时间。
Min:请求的最小服务器响应时间,单位毫秒。
Max:请求的最大服务器响应时间,单位毫秒。
Content Size:单个请求的大小,单位字节。
reqs/sec:是每秒钟请求的个数。
相比于LoadRunner
,Locust
的结果展现十分简单,主要就四个指标:并发数
、RPS
、响应时间
、异常率
。但对于大多数场景来讲,这几个指标已经足够了。
在上图中,RPS
和平均响应时间
这两个指标显示的值都是根据最近2秒请求响应数据计算获得的统计值,咱们也能够理解为瞬时值。
若是想看性能指标数据的走势,就能够在Charts
栏查看。在这里,能够查看到RPS
和平均响应时间
在整个运行过程当中的波动状况。
除了以上数据,Locust
还提供了整个运行过程数据的百分比统计值,例如咱们经常使用的90%响应时间
、响应时间中位值;平均响应时间和错误数的统计
,该数据能够经过Download response time distribution CSV和Download request statistics CSV
得到,数据展现效果以下所示。
locust虽然使用方便,可是加压性能和响应时间上面仍是有差距的,若是项目有很是大的并发加压请求,能够选择wrk
对比方法与结果:
能够准备两台服务器,服务器A做为施压方,服务器B做为承压方
服务器B上简单的运行一个nginx服务就好了
服务器A上能够安装一些经常使用的压测工具,好比locust、ab、wrk
实测下来,施压能力上 wrk > golang >> ab > locust
由于locust一个进程只使用一核CPU,因此用locust压测时,必须使用主从分布式(zeromq通信)模式,并根据服务器CPU核数来起slave节点数
wrk约为55K QPSgolang net/http 约 45K QPSab 大约 15K QPSlocust 最差,并且response time明显比较长