locust的使用

Locust是什么?

Locust 是一个开源负载测试工具。使用 Python 代码定义用户行为,也可以仿真百万个用户。
Locust 是非常简单易用,分布式,用户负载测试工具。Locust 主要为网站或者其他系统进行负载测试,能测试出一个系统可以并发处理多少用户。
Locust 是完全基于时间的,因此单个机器支持几千个并发用户。相比其他许多事件驱动的应用,Locust 不使用回调,而是使用轻量级的处理方式 gevent。

安装

pip  install  locustio

如果你打算通过多进程或多机,分布式地运行Locust,我们建议你也安装pyzmq

pip install pyzmq

TaskSet类

每个Locust类必须有一个指向一个TaskSettask_set属性。
TaskSet是任务的集合,这些任务是普通的python可调用对象。
当负载测试启动的时候,产生的每一个Locust类的实例都会开始执行它们的TaskSet。接下来发生的是,每个TaskSet会选择它的任务中的一个,并且调用它。接下来等待min_waitmax_wait毫秒,然后它会再选择下一个要被调用的任务,再等待,等等。

声明任务

为TaskSet声明任务最典型的方式是使用task装饰器。
下面是一个例子:

def index(l):
    l.client.get("/")

def stats(l):
    l.client.get("/stats/requests")

class UserTasks(TaskSet):
    # one can specify tasks like this
    tasks = [index, stats]
    
    # but it might be convenient to use the @task decorator
    @task(3)
    def task1(self):
        self.client.get("/does_not_exist")

    @task(6)
    def task2(self):
        pass

class WebsiteUser(HttpLocust):
    """
    Locust user class that does requests to the locust web server running on localhost
    """
    host = "http://127.0.0.1:8089"
    min_wait = 2000
    max_wait = 5000
    task_set = UserTasks
  • @task装饰器带一个可选的weight参数,它用于指定任务的执行比例。在下面的例子中,task2的执行次数是task1的两倍
  • TaskSet支持嵌套
class MyTaskSet(TaskSet):  
    @task
    class SubTaskSet(TaskSet):
        @task
        def my_task(self):
            pass
  • on_start函数
    TaskSet类可以定义一个on_start方法,当模拟用户开始执行TaskSet类的时候,on_start方法会被调用。

HttpLocust类

本文已经包含了Locust用户的任务调度部分,为了真正的给一个系统进行负载测试,我们需要生成HTTP请求,HttpLocust类的存在,就是为了解决这个问题。当使用HttpLocust类的时候,每个实例都有一个client属性---它是能够用于生成HTTP请求的HttpSession类的实例

from locust import HttpLocust, TaskSet, task

class MyTaskSet(TaskSet):  
    @task(2)
    def index(self):
        self.client.get("/")

    @task(1)
    def about(self):
        self.client.get("/about/")

class MyLocust(HttpLocust):  
    task_set = MyTaskSet
    min_wait = 5000
    max_wait = 15000
  1. 使用上面的Locust类,每个模拟用户在请求之间都会等待5-15秒,并且/的请求次数是/about/的两倍。
  1. 用心的读者可能会觉得很奇怪:在TaskSet内部我们使用self.client而非self.locust.client开引用HttpSession实例,我们能这么做是因为:TaskSet类有一个便捷的被称作client的属性,它简单的返回self.locust.client
  • 生成GET请求的例子
response = self.client.get("/about")  
print "Response status code:", response.status_code  
print "Response content:", response.content  
  • 生成POST请求的例子
response = self.client.post("/login", {"username":"testuser", "password":"secret"})  
  • 人工控制一个请求被视为成功还是失败

默认情况下,除非HTTP响应码是ok(2xx),否则请求就会被标记为失败。大多数情况下,默认的情况就是我们想要的。然而有时:比如说你期望返回404,或者是测试一个即使发生错误,仍然返回200 OK的系统,就存在人工控制locust将请求视为成功还是失败的需求。 通过使用catch_response参数和with语句,可以把一个响应码是okay的请求标记成失败

with client.get("/", catch_response=True) as response:  
    if response.content != "Success":
        response.failure("Got wrong response")

正如可以把响应码为OK的请求标记为失败,也可以使用catch_response参数和with语句,将返回http错误代码的请求在统计中报告为成功。

with client.get("/does_not_exist/", catch_response=True) as response:  
    if response.status_code == 404:
        response.success()
  • 安全模式

HTTP客户端被配置成以安全模式运行,任何由于连接错误,超时之类导致失败的请求都不会抛出异常,而是返回一个空的虚拟的Response对象,在Locust的统计中请求会被报告为一个失败。被返回的虚拟的Response对象的content属性被设置为None,status_code属性被设置为0

  • 将到具有动态参数的URL的请求分组

对于网站来说,拥有URL中包含某种动态参数的页面是非常普遍的。通常在Locust的统计中,把这些URL分成一组是有意义的。可以通过给HttpSession实例的请求方法传递name参数,来完成这件事。
例子:

# Statistics for these requests will be grouped under: /blog/?id=[id]
for i in range(10):  
    client.get("/blog?id=%i" % i, name="/blog?id=[id]")

启动

  • 如果运行的文件名称为locustfile.py 则可以直接运行
locust --host=http://example.com
  • 如果locust file被放到了其他的地方,我们可以运行
 locust -f 当前文件夹路径/my_file.py --host=http://example.com
  • 如果需要多线程分布式运行locust,启动的时候需要指定masterslave
 locust -f 当前文件夹路径/my_file.py --host=http://example.com  --master 

然后我们可以启动任意数量的slave进程:(用master机器的ip替换192.168.0.14)

locust -f my_locustfile.py --slave --master-host=192.168.0.14

分布式运行Locust

参数

属性 解释
-f 文件名
--host 运行的接口的host
--master 以master的模式运行locust,web接口会运行在这个节点上
--slave 以slave模式运行locust。
--master-host=X.X.X.X --slave一起使用,用来设置master节点的ip或主机名(默认是127.0.0.1)
--master-port=5557 --slave一起使用,用来设置master节点的端口号(默认是5557),注意locust既会使用指定的端口号,又会使用指定的端口号+1,因此如果设置为5557,那么locust既会使用5557,也会使用5558
--master-bind-host=X.X.X.X --master一起使用,决定master节点绑定到哪一个网络接口,默认是*(所有可用的网络接口)

min_wait和max_wait属性

除了task_set属性,也可以声明min_waitmax_wait属性,它们是一个模拟用户在执行任务之间等待的最大和最小时间,单位是毫秒min_wait和max_wait默认是1000,因此如果没有声明min_waitmax_waitlocust在执行每个任务之间总是会等待1秒。
使用下面的locustfile,在任务之间每个用户等待5-15秒:

from locust import Locust, TaskSet, task

class MyTaskSet(TaskSet):  
    @task
    def my_task(self):
        print "executing my_task"

class MyLocust(Locust):  
    task_set = MyTaskSet
    min_wait = 5000
    max_wait = 15000

参考:
http://timd.cn/2015/09/17/locust/
https://my.oschina.net/u/2306127/blog/482625

你可能感兴趣的:(locust的使用)