« 上一篇下一篇 »

服务器​日常的测试程序,开源性能测试工具Locust 应用实例

     对于常见的HTTP(S)协议,Locust已经实现了HttpLocust类,其client属性绑定了HttpSession类,而HttpSession又继承自requests.Session。因此在测试HTTP(S)的Locust脚本中,我们可以通过client属性来使用Python requests库的所有方法,包括GET/POST/HEAD/PUT/DELETE/PATCH等,调用方式也与requests完全一致。另外,由于requests.Session的使用,因此client的方法调用之间就自动具有了状态记忆的功能。常见的场景就是,在登录系统后可以维持登录状态的Session,从而后续HTTP请求操作都能带上登录态。

而对于HTTP(S)以外的协议,我们同样可以使用Locust进行测试,只是需要我们自行实现客户端。在客户端的具体实现上,可通过注册事件的方式,在请求成功时触发events.request_success,在请求失败时触发events.request_failure即可。然后创建一个继承自Locust类的类,对其设置一个client属性并与我们实现的客户端进行绑定。后续,我们就可以像使用HttpLocust类一样,测试其它协议类型的系统。

      经过一段时间的摸索,包括通读Locust官方文档和项目源码,并且在多个性能测试项目中对Locust进行应用实践,事实证明,Locust完全能满足日常的性能测试需求,LoadRunner能实现的功能Locust也基本都能实现。
本文将从Locust的功能特性出发,结合实例对Locust的使用方法进行介绍。考虑到大众普遍对LoadRunner比较熟悉,在讲解Locust时也会采用LoadRunner的一些概念进行类比

1、安装
这个工具是用python写的,首先我们要安装框架

首先升级pip,不然可能会报错
pip install --upgrade pip

然后安装Locust
pip install Locust

安装完成

2、编写Locust file

这里是压测软件的主要功能

vim locustfile.py


from locust import HttpLocust, TaskSet

#登陆操作
def login(l):
    l.client.post("/phpadmin/index.php", {"pma_username":"hugw", "pma_password":"RedHat"})

#登出操作
def logout(l):
    l.client.post("/phpadmin/logout.php", {"db":"&", "token":"be2cb767a5829a398ef5a4c0dcafe504"})

#请求index
def index(l):
    l.client.get('/phpadmin/index.php')

class UserBehavior(TaskSet):
    tasks = {index}

#执行登陆和登出
    def on_start(self):
        login(self)

    def on_stop(self):
        logout(self)

class WebsiteUser(HttpLocust):
    task_set = UserBehavior
    min_wait = 3000
    max_wait = 6000


启动压测程序
如果配置文件名字是locustfile.py,那么直接运行就好
启动成功会监听8089端口,
这里的 http://192.168.1.9 是要压测的网站域名

[root@slave locust]# locust -H http://192.168.1.9
[2018-04-12 19:41:37,086] slave/INFO/locust.main: Starting web monitor at *:8089
[2018-04-12 19:41:37,086] slave/INFO/locust.main: Starting Locust 0.8.1


配置压测集群(可选)

启动压测主程序,跟上面一样,后面加上参数 --master
启动成功会监听8089端口,
这里的 http://192.168.1.9 是要压测的网站域名

[root@slave locust]# locust -H http://192.168.1.9 --master
[2018-04-12 22:20:12,889] slave/INFO/locust.main: Starting web monitor at *:8089
[2018-04-12 22:20:12,891] slave/INFO/locust.main: Starting Locust 0.8.1
[2018-04-12 22:20:47,669] slave/INFO/locust.runners: Client 'k8s_cf9d5e7c4238f74363180e5b3dcb0ae4' reported as ready. Currently 1 clients ready to swarm.
[2018-04-12 22:21:02,066] slave/INFO/locust.runners: Sending hatch jobs to 1 ready clients
[2018-04-12 22:21:12,069] slave/INFO/locust.runners: Resetting stats

启动slave
先把 locustfile.py 分发到slave机器上,安装locust,然后启动

[root@k8s locust]# locust -H http://192.168.1.9 --slave --master-host=master_IP
[2018-04-12 02:21:48,045] k8s/INFO/locust.main: Starting Locust 0.8.1
[2018-04-12 02:22:02,487] k8s/INFO/locust.runners: Hatching and swarming 20 clients at the rate 2 clients/s...
[2018-04-12 02:22:12,509] k8s/INFO/locust.runners: All locusts hatched: WebsiteUser: 20
[2018-04-12 02:22:12,509] k8s/INFO/locust.runners: Resetting stats

然后登陆master压测就行了

3、开始压测

填写你要模拟的用户数量,这里填500用户,以每秒50数量增加,点击start 开始

 

查看压测请求情况

 

在Locust类中,具有一个client属性,它对应着虚拟用户作为客户端所具备的请求能力,也就是我们常说的请求方法。通常情况下,我们不会直接使用Locust类,因为其client属性没有绑定任何方法。因此在使用Locust时,需要先继承Locust类,然后在继承子类中的client属性中绑定客户端的实现类。

    对于常见的HTTP(S)协议,Locust已经实现了HttpLocust类,其client属性绑定了HttpSession类,而HttpSession又继承自requests.Session。因此在测试HTTP(S)的Locust脚本中,我们可以通过client属性来使用Python requests库的所有方法,包括GET/POST/HEAD/PUT/DELETE/PATCH等,调用方式也与requests完全一致。另外,由于requests.Session的使用,因此client的方法调用之间就自动具有了状态记忆的功能。常见的场景就是,在登录系统后可以维持登录状态的Session,从而后续HTTP请求操作都能带上登录态。

而对于HTTP(S)以外的协议,我们同样可以使用Locust进行测试,只是需要我们自行实现客户端。在客户端的具体实现上,可通过注册事件的方式,在请求成功时触发events.request_success,在请求失败时触发events.request_failure即可。然后创建一个继承自Locust类的类,对其设置一个client属性并与我们实现的客户端进行绑定。后续,我们就可以像使用HttpLocust类一样,测试其它协议类型的系统。

原理就是这样简单!

在Locust类中,除了client属性,还有几个属性需要关注下:

task_set: 指向一个TaskSet类,TaskSet类定义了用户的任务信息,该属性为必填;
max_wait/min_wait: 每个用户执行两个任务间隔时间的上下限(毫秒),具体数值在上下限中随机取值,若不指定则默认间隔时间固定为1秒;
host:被测系统的host,当在终端中启动locust时没有指定--host参数时才会用到;
weight:同时运行多个Locust类时会用到,用于控制不同类型任务的执行权重。
测试开始后,每个虚拟用户(Locust实例)的运行逻辑都会遵循如下规律:

先执行WebsiteTasks中的on_start(只执行一次),作为初始化;
从WebsiteTasks中随机挑选(如果定义了任务间的权重关系,那么就是按照权重关系随机挑选)一个任务执行;
根据Locust类中min_wait和max_wait定义的间隔时间范围(如果TaskSet类中也定义了min_wait或者max_wait,以TaskSet中的优先),在时间范围中随机取一个值,休眠等待;
重复2~3步骤,直至测试任务终止。
class TaskSet
再说下TaskSet类。

     性能测试工具要模拟用户的业务操作,就需要通过脚本模拟用户的行为。在前面的比喻中说到,TaskSet类好比蝗虫的大脑,控制着蝗虫的具体行为。

具体地,TaskSet类实现了虚拟用户所执行任务的调度算法,包括规划任务执行顺序(schedule_task)、挑选下一个任务(execute_next_task)、执行任务(execute_task)、休眠等待(wait)、中断控制(interrupt)等等。在此基础上,我们就可以在TaskSet子类中采用非常简洁的方式来描述虚拟用户的业务测试场景,对虚拟用户的所有行为(任务)进行组织和描述,并可以对不同任务的权重进行配置。

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