Locust性能测试工具核心技术@task和@events

开发 开发工具
Tasks和Events是Locust性能测试工具的核心技术,有了它们,Locust才能称得上是一个性能工具。

[[403128]]

本文转载自微信公众号「dongfanger」,作者dongfanger。转载本文请联系dongfanger公众号。

Tasks和Events是Locust性能测试工具的核心技术,有了它们,Locust才能称得上是一个性能工具。

Tasks

从上篇文章知道,locustfile里面必须要有一个类,继承User类,当性能测试开始后,会产生一个User类实例,这就是常说的模拟用户。这些用户会选择task执行,休眠一会,再选择新的task,不断迭代。

task是Python中的可调用对象,它是一项任务,对于Web系统来说,可以是登录、查询、下订单、支付等等。

@task装饰器

@task是定义task最简单直接的方式,比如:

  1. from locust import User, task, constant 
  2.  
  3. class MyUser(User): 
  4.     wait_time = constant(1) 
  5.  
  6.     @task 
  7.     def my_task(self): 
  8.         print("User instance (%r) executing my_task" % self) 

@task有一个可选参数,用来设置task的选择权重,比如:

  1. from locust import User, task, between 
  2.  
  3. class MyUser(User): 
  4.     wait_time = between(5, 15) 
  5.  
  6.     @task(3) 
  7.     def task1(self): 
  8.         pass 
  9.  
  10.     @task(6) 
  11.     def task2(self): 
  12.         pass 

task2比task1被选择的可能性大两倍。

tasks属性

除了@task装饰器,还可以设置User类的tasks属性来定义任务,比如:

  1. from locust import User, constant 
  2.  
  3. def my_task(user): 
  4.     pass 
  5.  
  6. class MyUser(User): 
  7.     tasks = [my_task] 
  8.     wait_time = constant(1) 

注意,my_task()函数有一个参数,它是User类的实例。

tasks可以是一个列表:

  1. tasks = [my_task1, my_task2, my_task3] 

Locust会使用Python中的random.choice()从里面随机选取。

tasks也可以是一个字典:

  1. {my_task: 3, another_task: 1} 

后面的int型键值代表的是被选择权重,这个字典等价于列表:

  1. [my_task, my_task, my_task, another_task] 

@tag装饰器

@tag用来打标记,在运行时选择哪些task执行,哪些task不执行。比如:

  1. class MyUser(User): 
  2.     wait_time = constant(1) 
  3.  
  4.     @tag('tag1'
  5.     @task 
  6.     def task1(self): 
  7.         pass 
  8.  
  9.     @tag('tag1''tag2'
  10.     @task 
  11.     def task2(self): 
  12.         pass 
  13.  
  14.     @tag('tag3'
  15.     @task 
  16.     def task3(self): 
  17.         pass 
  18.  
  19.     @task 
  20.     def task4(self): 
  21.         pass 
  • 如果使用--tags tag1,那么只有task1和task2会被选择。
  • 如果使用--tags tag2 tag3,那么只有task2和task3会被选择。
  • 如果使用--exclude-tags tag3,那么只有task1、task2和task4会被选择。

注意,exclude的优先级更高,如果某个tag既包括又排除,那么会被排除。

Events

@task定义了性能测试的执行动作,@events作为补充,定义了测试开始前和测试结束后的处理。

注意,每个模拟用户开始和结束的处理是使用的User类的on_start()和on_stop()方法。

test_start和test_stop

测试开始前和测试结束后触发。示例:

  1. from locust import events 
  2.  
  3. @events.test_start.add_listener 
  4. def on_test_start(environment, **kwargs): 
  5.     print("A new test is starting"
  6.  
  7. @events.test_stop.add_listener 
  8. def on_test_stop(environment, **kwargs): 
  9.     print("A new test is ending"

分布式执行时,它们只会在master节点生效。

init

init和test_start不同,它会在每个Locust进程开始时触发,分布式执行时,每个节点(worker进程)都会生效。

  1. from locust import events 
  2. from locust.runners import MasterRunner 
  3.  
  4. @events.init.add_listener 
  5. def on_locust_init(environment, **kwargs): 
  6.     if isinstance(environment.runner, MasterRunner): 
  7.         print("I'm on master node"
  8.     else
  9.         print("I'm on a worker or standalone node"

Events是一项hook技术,在学习Locust高级用法时再做进一步介绍。

Locust项目结构

官方建议如下:

common/

__init__.py

auth.py

config.py

locustfile.py或者locustfiles/

api.py

website.py

requirements.txt

FastHttpUser

从上篇文章可以知道,HttpUser类比User类更常用,它的client属性是HttpSession类(requests.Session子类)的一个实例,可以使用requests发HTTP请求:

  1. # 使用HttpUser 
  2. from locust import HttpUser,task,constant 
  3.  
  4.  
  5. class MyUser(User): 
  6.     wait_time = constant(1) 
  7.      
  8.     @task 
  9.     def my_task1(self): 
  10.         with self.client.get("https://www.baidu.com/", catch_response=Trueas res: 
  11.             if res.status_code == 200: 
  12.                 print("成功"
  13.             else
  14.                 print("失败"

但是requests性能是不太好的,如果要产生更高的压力,建议使用FastHttpUser,性能可以提升5到6倍:

  1. # 使用FastHttpUser 
  2. from locust import task, constant 
  3. from locust.contrib.fasthttp import FastHttpUser 
  4.  
  5.  
  6. class MyUser(FastHttpUser): 
  7.     wait_time = constant(1) 
  8.  
  9.     @task 
  10.     def my_task(self): 
  11.         with self.client.get("https://www.baidu.com/", catch_response=Trueas response: 
  12.             if response.status_code == 200: 
  13.                 print("成功"
  14.             else
  15.                 print("失败"

由于它们的API不一样,都有各自的适用场景,所以FastHttpUser不能完全替代HttpUser。

小结

本文严格来说是上篇文章《locustfile中的User类和HttpUser类》的下篇,介绍了核心技术Tasks和Events,并给出了官方推荐的项目结构,最后介绍了比HttpUser性能更好的FastHttpUser,如果想要更多的并发,可以考虑使用后者。经过这两篇文章的学习,已经可以开始动手实践使用Locust进行性能测试了。如果使用locust命令启动后,无法打开网页,可以试试加上参数:locust --web-host="127.0.0.1"。

参考资料:

https://zhuanlan.zhihu.com/p/118470760

https://docs.locust.io/en/stable/writing-a-locustfile.html#tasks

https://www.axihe.com/tools/locust/increase-performance.html

 

https://blog.csdn.net/u012002125/article/details/113363768

 

责任编辑:武晓燕 来源: dongfanger
相关推荐

2021-05-07 07:27:51

Python测试工具

2012-08-01 10:50:48

性能测试测试架构

2010-06-07 14:42:47

Linux性能测试工具

2010-06-04 16:07:09

Linux 性能测试工

2010-06-13 17:16:15

Linux性能测试工具

2024-03-06 18:09:06

Linux性能工具

2016-09-14 11:09:06

Web工具运维

2010-06-04 09:12:23

Linux性能测试工具

2010-10-15 09:37:14

MySQL性能测试

2012-12-24 22:54:31

2010-06-10 17:37:08

Linux 性能测试工

2017-09-19 18:34:16

Mysql数据库性能测试

2023-07-13 23:21:02

2021-05-17 10:44:24

Python 工具编程语言

2011-04-07 13:53:25

Web工具

2022-05-07 14:31:46

物联网

2009-06-26 10:22:58

JSF测试

2011-05-31 18:09:05

动态测试

2014-04-02 14:03:04

网站速度性能测试

2013-07-26 09:51:12

网站性能网站测试性能测试
点赞
收藏

51CTO技术栈公众号