关于spring:性能测试locust简介及使用

8次阅读

共计 5861 个字符,预计需要花费 15 分钟才能阅读完成。

1、JMeter 和 Locust 的比照阐明

1)开源许可证

工具许可范畴的问题是最重要的问题之一,因为您可能想晓得是否须要领取额定的第三方工具来实现负载测试。如果某个工具是开源的,那么您简直能够实现为性能测试设置的任何指标,而无需任何额定付款。开源 JMeter 和 Locust 也不例外。

JMeter 和 Locust 都提供了许可软件许可证,该许可证反对免费软件,对软件的散发形式提出最低要求。JMeter 是由 Apache 开发的,它基于 Apache License 2.0,而 Locust 是由一个由社区驱动的开发人员组成的小团队开发的,基于 MIT 许可证。在这两种状况下,这些工具都是开源的,容许您自在应用它们,而不受任何应用限度。

2)负载测试创立和保护

性能测试工作流程有三个次要步骤:创立,运行和剖析。个别第一步是最耗时的。

编写 JMeter 性能测试的最罕用办法是应用其 GUI 模式。JMeter GUI 模式提供了一个桌面客户端,容许您轻松创立测试,而无需编写单行代码(直到您须要创立辣手的测试)。所以最简略的场景可能如下所示:

JMeter 非常简单,通常,即便是没有教训的工程师也能够毫无艰难地上手。然而如果须要,您能够应用 Java 在 GUI 和非 GUI 模式下应用代码。然而,因为脚本实现的复杂性(因为 JMeter 旨在与 GUI 模式一起应用)以及不足如何制作此类脚本的文档,因而这种形式在 JMeter 社区中并不风行。

Locust 则须要 python 编程根底。

3)反对的协定

现实状况下,您应该可能应用尽可能少的工具测试所有工具,只有它不会影响测试品质。

应用 JMeter,您能够应用残缺的内置函数和第三方插件,在一个中央创立所有内容的性能测试。您无需编码即可测试不同的协定甚至数据库。这些包含 JDBC,FTP,LDAP,SMTP 等。JMeter 还能够通过 jar 包扩大,比方加载 jython,能够应用 python 脚本。

依据文档,Locust 次要用于基于 HTTP Web 的测试。但能够扩大其默认性能并创立自定义 Python 函数来测试能够应用 Python 编程语言进行测试的任何内容。

4)并发用户数

JMeter 和 Locust 有齐全不同的形式来解决机器资源。JMeter 有一个基于线程的模型,它为每个用户调配一个独自的线程。每个步骤的线程调配和基准测试须要大量资源,这就是为什么 JMeter 对于您能够在一台机器上模仿的用户数量十分无限的起因。您能够在一台计算机上运行的用户数取决于许多因素,如脚本复杂性,硬件,响应大小等。如果您的脚本很简略,JMeter 容许您在一台机器上运行多达数千个,但脚本执行逐步变得不牢靠。

Locust 有齐全不同的用户模仿模型,它基于事件和异步办法(协程),以 gevent coroutine 作为整个过程的基石。这种实现容许 Locust 框架在一台机器上轻松模仿数千个并发用户,即便是在非常规的笔记本电脑上,也可同时运行外部有许多步骤的简单测试。

5)加强灵活性

这两个工具提供绝对雷同的生成负载的形式 – 您能够指定在性能测试期间要应用的用户数以及它们应该减速的速度。

在 JMeter 中,您能够在指定字段的“线程组”控制器中配置负载:然而 JMeter 还有其余插件,能够让您配置非常灵活的负载。最好的办法之一是应用 Ultimate Thread Group,它容许用户制作十分具体的加载模式:

Locust 有不同的办法。当您运行性能脚本时,Locust 会主动在 http://localhost:8089 上启动 Web 界面的服务器,该界面为您提供仅指定线性负载的输出元素, 当然也能够命令行执行通过参数定制。

6)脚本录制

这是 JMeter 具备弱小劣势的中央,因为它具备脚本录制的内置性能,而 Locust 基本没有此性能。除此之外,还有许多第三方插件能够为 JMeter 制作脚本录制。记录此类脚本最不便的办法之一是应用 BlazeMeter chrome 扩大。

7)测试监控

JMeter 和 Locust 都提供了弱小的内置性能来监控性能脚本并剖析您的测试后果。JMeter 有许多不同的元素叫做监听器。每个侦听器都提供特定类型的监督,你也能够应用许多现有的自定义监听器扩大默认库。另一方面,JMeter 监听器在其运行的机器上耗费大量资源。这就是为什么通常,JMeter 是以非 GUI 模式执行的,没有任何监听器或监控过程,在这种状况下,可应用 3 方工具,如 BlazeMeter。

Locust 的监测能力稍弱,不过简直提供了所有可用于监控根本负载的信息。在脚本运行期间,Locust 运行一个简略的 Web 服务器,

2、编写 Locust 示例代码

locust_sample.py

from locust import HttpUser, TaskSet, task
class WebsiteTasks(TaskSet):
    def on_start(self):
        self.client.post("/login", { "username": "test", "password": "123456"})

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

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

    tasks = {index: 2, about: 1} # 与装璜器成果统一

class WebsiteUser(HttpUser):
    # task_set = WebsiteTasks  # Usage of User.task_set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks])
    tasks = [WebsiteTasks]
    host = "http://debugtalk.com"
    min_wait = 1000
    max_wait = 5000

启动测试:locust -H http://debugtalk.com -f locust_sample.py

3、Locust 类具体解说

在 Locust 类中,具备一个 client 属性,它对应着虚构用户作为客户端所具备的申请能力,也就是咱们常说的申请办法。通常状况下,咱们不会间接应用 Locust 类,因为其 client 属性没有绑定任

何办法。因而在应用 Locust 时,须要先继承 Locust 类,而后在继承子类中的 client 属性中绑定客户端的实现类。对于常见的 HTTP(S)协定,Locust 曾经实现了 HttpUser(1.0 之前应用 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 属性并与咱们实现的客户端进行绑定。后续,咱们就能够像应用 HttpUser 类一样,测试其它协定类型的零碎。

原理就是这样简略!

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

  • tasks(1.0 以下是 task_set): tasks = [WebsiteTasks] Collection of python callables and/or TaskSet classes that the Locust user(s) will run.指向一个 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 步骤,直至测试工作终止。

4、TaskSet 类具体解说

性能测试工具要模仿用户的业务操作,就须要通过脚本模仿用户的行为。在后面的比喻中说到,TaskSet 类好比蝗虫的大

脑,管制着蝗虫的具体行为。

具体地,TaskSet 类实现了虚构用户所执行工作的调度算法,包含布局工作执行程序(schedule_task)、筛选下一个任

务(execute_next_task)、执行工作(execute_task)、休眠期待(wait)、中断管制(interrupt)等等。在此基

础上,咱们就能够在 TaskSet 子类中采纳十分简洁的形式来形容虚构用户的业务测试场景,对虚构用户的所有行为(工作

)进行组织和形容,并能够对不同工作的权重进行配置。

在 TaskSet 子类中定义工作信息时,能够采取两种形式,@task 装璜器和 tasks 属性。

采纳 @task 装璜器定义工作信息时,形容模式如下:

class WebsiteTasks(TaskSet):
    def on_start(self):
        self.client.post("/login", { "username": "test", "password": "123456"})

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

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

采纳 tasks 属性定义工作信息时,形容模式如下:

class WebsiteTasks(TaskSet):
    def on_start(self):
        self.client.post("/login", { "username": "test", "password": "123456"})

    # @task(2)
    def index(self):
        self.client.get("/")

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

    tasks = {index: 2, about: 1}  # 与装璜器成果统一

在 TaskSet 子类中除了定义工作信息,还有一个是常常用到的,那就是 on_start 函数。这个和 LoadRunner 中的 vuser_init 性能雷同,在正式执行测试前执行一

次,次要用于实现一些初始化的工作。例如,当测试某个搜寻性能,而该搜寻性能又要求必须为登录态的时候,就能够先在 on_start 中进行登录操作;后面也提 到,HttpUser 应用到了 requests.Session,因而后续所有工作执行过程中就都具备登录态了。

5、实战测试

1)测试代码

from locust import HttpUser, TaskSet, task
class WebsiteTasks(TaskSet):
    def on_start(self):
        # self.client.post("/login", { "username": "test", "password": "123456"})
        self.client.get("/login?key=00d91e8e0cca2b76f515926a36db68f5&phone=13594347817&passwd=123456")

    # @task(2)
    def videoCategory(self):
        self.client.get("/videoCategory")

    # @task(1)
    def videoRecommend(self):
        self.client.get("/videoRecommend?id=127398")

    def todayVideo(self):
        self.client.get("/todayVideo")

    def getJoke(self):
        self.client.get("/getJoke?page=1&count=2&type=video")

    def novelSearchApi(self):
        self.client.get("/searchPoetry?name= 古风二首 %20 二")

    tasks = {videoCategory: 2, videoRecommend: 1, todayVideo: 2, getJoke: 3, novelSearchApi: 2}  # 与装璜器成果统一

class WebsiteUser(HttpUser):
    # https://blog.csdn.net/c__chao/article/details/78573737
    # task_set = WebsiteTasks  # Usage of User.task_set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks])
    tasks = [WebsiteTasks]
    host = "https://api.apiopen.top"
    min_wait = 1000
    max_wait = 5000

2)测试后果截图

①配置模仿的用户数量、每秒减少的用户数、测试地址

②运行时数据

③运行的异样信息

④下载运行后果

⑤TPS 每秒申请数

⑥响应工夫

⑦用户数

3)测试时服务器的数据

后续在做记录

集体博客 蜗牛

正文完
 0