接口压测工具Locust进阶用法

2016-12-04

这篇记录是第一个版本的补充和丰富
Locust在代码中,相应的代码的含义和使用,网上有些教程,这篇文章就不错编写一个Locust文件

web页面设置并发


Number of users to simulate的意思好理解,就是模拟的用户并发数目。
Hatch rate(users spawned/second)的意思就是,每秒中孵化的用户数目,也就是每秒中增加的用户数目。如下图


上图中就是并发数从0到100的过程,每秒中增加5个用户。

这个平均响应时间也是与上图对应,从图中可以看出,当并发数稳定后,响应时长也相对稳定了,响应时间也提高了。

使用消息队列Queue

使用代码相对于使用工具,一个相对来说更好的优点就是灵活。比如处理起接口之间的依赖关系。比如,我要测试取消订单的接口,要取消订单,首先这个订单要创建成功过。用Locust的第一个想法是,直接创建一个task,在一个任务中,将两个接口的请求放在一个task中,先创建订单,然后之间把创建好的订单送给取消订单的接口去请求。

需要想想,这样是否合适?这样实际上是用一个task进行了两个接口的请求的测试。而我们是要看的一个接口的性能。所以这种方式并不是很合适。如何做?我想到了用消息队列,而不用list,因为我要保证我的数据的唯一性。一个订单只能取消一次,所以要用Queue。关于Python中的Queue的用法,自行谷歌。

1
2
3
4
5
6
7
8
9
import Queue
#实例化queue
q_order_create=Queue.Queue()
#在queue中赛数据
q_order_create.put(e_id)
#判断queue是否为空,当为空时,queue.empty()==Ture
while (q_order_create.empty()==False):
#从queue中取数据
bds_id=q_order_create.get()

在创建订单的接口的task中填订单号,在取消订单的接口的task中取订单号就可以了。

on_start函数

有必要说下这个函数,这个函数在其他task执行之前,最先执行,而且只执行一次。可以把on_start函数看成是为其他接口准备条件的。比如token,接口请求是需要token进行校验的,但是也不能每个接口请求的时候都要请求一个获取token的接口吧!所以请求token,获取token的功能就可以写进on_start函数。然后把token值赋值给self,这个类中的task就可以共用一个token了。

命令行调试

有时候每次都要刷新web界面,填入数据不方便调试,直接在命令行中调试就方便了。

1
locust -f  locust_test.py --host='http://api.g.caipiao.163.com' --no-web -c 1000 -r 10 -n 1000

接下来负载测试就会自动执行,按“ctrl+c”结束负载测试:

对于命令行中的参数的解释:–no-web是用来选择无浏览器模式,-c后面接的是模拟用户数,-r后面接的每秒模拟用户并发数,-n后面接的是模拟请求数。

成功或者失败可能会用到的钩子函数

比如

具体详见文章Locust还提供了如下7种有用的钩子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from locust import HttpLocust, TaskSet, task

class UserTask(TaskSet):
@task
def job(self):
with self.client.get('/', catch_response = True) as response:
if response.status_code == 200:
response.failure('Failed!')
else:
response.success()

class User(HttpLocust):
task_set = UserTask
min_wait = 1000
max_wait = 1000

上面的例子比较无聊(只是为了说明使用with语句及catch_response参数可以截获原始响应),把所有status_code是200的响应都当做失败响应。注意,这里success()和failure(str)的调用会体现在结果的统计上


注意其中的两个failure()和success()方法,这两个方法在上面代码中的执行,对应到web上的显示。当返回成功200时,执行failure方法,在web上显示是请求失败。

Locust源码简单阅读

直接取github上把源码拉下来简单的阅读下

isinstance用来判断是否是对应的类型

1
2
3
4
5
6
7
8
9
>>> a = "b"
>>>isinstance(a,str)
True
>>> isinstance(a,int)
False
>>> isinstance(a,(int,list,float))
False
>>> isinstance(a,(int,list,float,str))
True

dir([object]) 会返回object所有有效的属性列表。示例如下:

1
2
3
4
>>> import cv2
>>> mser = cv2.MSER()
>>> dir(mser)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'detect', 'empty', 'getAlgorithm', 'getBool', 'getDouble', 'getInt', 'getMat', 'getMatVector', 'getParams', 'getString', 'paramHelp', 'paramType', 'setAlgorithm', 'setBool', 'setDouble', 'setInt', 'setMat', 'setMatVector', 'setString']
  • locust中的clients.py文件用来实现client的网络请求,以及定义response是success和failure。
  • 其中的core.py文件是定义命令行中的命令的。如
    locust -f test.py
    其中的”-f”是“locustfile”
  • 还有其中的方法find_locustfile方法,可以用于借鉴,比如自己在找文件的时候。
  • 其中的main函数,用来处理函数parse_options,也就是命令行中输入的东西。
  • events.py文件用来加减locust中的各种event,例如失败和成功的数量

文章参考

编写一个Locust文件
Locust还提供了如下7种有用的钩子