开源性能测试工具Locust使用篇(三)
脚本增强
面对较复杂的测试场景,我们可能还是会感觉无从下手;例如,很多时候脚本需要做关联或参数化处理,Locust中就不知道怎么实现了。可能也是这方面的原因,感觉难以将Locust应用到实际的性能测试工作当中。其实这也跟Locust的目标定位有关,Locust的定位就是small and very hackable。但是小巧并不意味着功能弱,我们完全可以通过Python脚本本身来实现各种各样的功能。
在LoadRunner这款功能全面应用广泛的商业性能测试工具中,脚本增强无非就涉及到四个方面:
· 关联
· 参数化
· 检查点
· 集合点
a.关联:在某些请求中,需要携带之前从Server端返回的参数,因此在构造请求时需要先从之前请求的Response中提取出所需的参数,常见场景就是session_id。针对这种情况,LoadRunner手动进行关联处理时,主要是通过使用注册型函数,例如web_reg_save_param,对前一个请求的响应结果进行解析,根据左右边界或其它特征定位到参数值并将其保存到参数变量,然后在后续请求中使用该参数。采用同样的思想,我们在Locust脚本中也完全可以实现同样的功能,毕竟只是Python脚本,通过官方库函数re.search就能实现所有需求。甚至针对html页面,我们也可以采用lxml库,通过etree.HTML(html).xpath来更优雅地实现元素定位。
b.参数化:这一项极其普遍,主要是用在测试数据方面,其实也可以概括为三种类型。
· 循环取数据,数据可重复使用:e.g. 模拟3用户并发请求网页,总共有100个URL地址,每个虚拟用户都会依次循环加载这100个URL地址;
· 保证并发测试数据唯一性,不循环取数据:e.g. 模拟3用户并发注册账号,总共有90个账号,要求注册账号不重复,注册完毕后结束测试;
· 保证并发测试数据唯一性,循环取数据:模拟3用户并发登录账号,总共有90个账号,要求并发登录账号不相同,但数据可循环使用。
以上三种类型基本上可以覆盖我们日常性能测试工作中的所有参数化场景。
使用Python的list和queue数据结构即可!具体做法是,在WebsiteUser定义一个数据集,然后所有虚拟用户在WebsiteTasks中就可以共享该数据集了。如果不要求数据唯一性,数据集选择list数据结构,从头到尾循环遍历即可;如果要求数据唯一性,数据集选择queue数据结构,取数据时进行queue.get()操作即可,并且这也不会循环取数据;至于涉及到需要循环取数据的情况,那也简单,每次取完数据后再将数据插入到队尾即可,queue.put_nowait(data)
c.检查点
在Locust脚本中,只需要对响应的内容关键字进行assert xxx in response操作即可。
Locust运行模式
运行Locust时,通常会使用到两种运行模式:单进程运行和多进程分布式运行。
单进程运行模式的意思是,Locust所有的虚拟并发用户均运行在单个Python进程中,具体从使用形式上,又分为no_web和web两种形式。该种模式由于单进程的原因,并不能完全发挥压力机所有处理器的能力,因此主要用于调试脚本和小并发压测的情况。当并发压力要求较高时,就需要用到Locust的多进程分布式运行模式。从字面意思上看,可能第一反应就是多台压力机同时运行,每台压力机分担负载一部分的压力生成。的确,Locust支持任意多台压力机(一主多从)的分布式运行模式,但这里说到的多进程分布式运行模式还有另外一种情况,就是在同一台压力机上开启多个slave的情况。这是因为当前阶段大多数计算机的CPU都是多处理器(multiple processor cores),单进程运行模式下只能用到一个处理器的能力,而通过在一台压力机上运行多个slave,就能调用多个处理器的能力了。比较好的做法是,如果一台压力机有N个处理器内核,那么就在这台压力机上启动一个master,N个slave。当然,我们也可以启动N的倍数个slave,但是根据我的试验数据,效果跟N个差不多,因此只需要启动N个slave即可。
脚本调试
Locust脚本编写完毕后,在正式开始性能测试之前还需要先调试运行下。
不过,Locust脚本虽然为Python脚本,但却很难直接当做Python脚本运行起来,主要还是因为Locust脚本中引用了HttpLocust和TaskSet这两个类,如果要想直接对其进行调用测试,会发现编写启动脚本是一个比较困难的事情。因为这个原因,刚接触Locust的同学可能就会觉得Locust脚本不好调试。
但这个问题也能克服,那就是借助Locust的单进程no_web运行模式。
在Locust的单进程no_web运行模式中,我们可以通过--no_web参数,指定并发数(-c)和总执行次数(-n),直接在Terminal中执行脚本。
在此基础上,当我们想要调试Locust脚本时,就可以在脚本中需要调试的地方通过print打印日志,然后将并发数和总执行次数都指定为1,执行形式如下所示。
$ locust -f locustfile.py --no_web -c 1 -n 1
通过这种方式,我们就能很方便地对Locust脚本进行调试了
执行测试
Locust脚本调试通过后,就算是完成了所有准备工作,可以开始进行压力测试了。Locust是通过在Terminal中执行命令进行启动的,通用的参数有如下两个:
· -H, --host:被测系统的host,若在Terminal中不进行指定,就需要在Locust子类中通过host参数进行指定;
· -f, --locustfile:指定执行的Locust脚本文件;
除了这两个通用的参数,我们还需要根据实际测试场景,选择不同的Locust运行模式,而模式的指定也是通过其它参数来进行控制的
单进程运行
no_web
如果采用no_web形式,则需使用--no-web参数,并会用到如下几个参数。
· -c, --clients:指定并发用户数;
· -n, --num-request:指定总执行测试;
· -r, --hatch-rate:指定并发加压速率,默认值位1。
web
如果采用web形式,,则通常情况下无需指定其它额外参数,Locust默认采用8089端口启动web;如果要使用其它端口,就可以使用如下参数进行指定。
· -P, --port:指定web端口,默认为8089.
此时,Locust并没有开始执行测试,还需要在Web页面中配置参数后进行启动。
如果Locust运行在本机,在浏览器中访问http://localhost:8089即可进入Locust的Web管理页面;如果Locust运行在其它机器上,那么在浏览器中访问http://locust_machine_ip:8089即可。
在Locust的Web管理页面中,需要配置的参数只有两个:
· Number of users to simulate: 设置并发用户数,对应中no_web模式的-c, --clients参数;
· Hatch rate (users spawned/second): 启动虚拟用户的速率,对应着no_web模式的-r, --hatch-rate参数。
参数配置完毕后,点击【Start swarming】即可开始测试
多进程分布式运行
不管是单机多进程,还是多机负载模式,运行方式都是一样的,都是先运行一个master,再启动多个slave。
启动master时,需要使用--master参数;同样的,如果要使用8089以外的端口,还需要使用-P, --port参数。
master启动后,还需要启动slave才能执行测试任务。
启动slave时需要使用--slave参数;在slave中,就不需要再指定端口了
如果slave与master不在同一台机器上,还需要通过--master-host参数再指定master的IP地址。
master和slave都启动完毕后,就可以在浏览器中通过http://locust_machine_ip:8089进入Locust的Web管理页面了。使用方式跟单进程web形式完全相同,只是此时是通过多进程负载来生成并发压力,在web管理界面中也能看到实际的slave数量
测试结果展示
在执行测试的过程中,我们可以在web界面中实时地看到结果运行情况。
Locust的结果展示十分简单,主要就四个指标:并发数、RPS、响应时间、异常率。但对于大多数场景来说,这几个指标已经足够。
以上这些原理的学习均来自大牛博客,讲解很透彻,重要的是自己要动手实践,技术性的东西看原理是记不住的,需要练手。地址https://blog.csdn.net/lizzy05/article/details/70792702