性能测试之Locust

340 阅读6分钟

前言:从何得知locust的?

话说,在很久很久以前,哈哈哈,不扯了,聊正事儿~~ 记得有一次公司搞活动,
线上的一个司庆活动,需要进行抽奖压测,我的主管告诉我这个任务交给我了,
当时其实我内心十分激动,但是表面表现的难为情,就是让自己闪亮登场,
哈哈哈,内心戏十足。
计划是使用jmeter,但是当时我的对jmeter不是非常熟悉,也不敢使用,
因为如果开始压测出现问题,我根本解决不了,只能去百度有没有其他压测工具,结果就结识了locust

那什么是locust?

官方介绍:

Locust is an easy to use, scriptable and scalable performance testing tool.
You define the behaviour of your users in regular Python code, instead of
being stuck in a UI or restrictive domain specific language.
This makes Locust infinitely expandable and very developer friendly.
To start using Locust, go to [Installation(https://docs.locust.io/en/stable/installation.html#installation)

解释: Locust是一个易于使用、可编写脚本且可扩展的性能测试工具。 您可以在常规Python代码中定义用户的行为,而不是停留在UI或限制性的领域特定语言中。 这使得Locust具有无限的可扩展性,并且对开发人员非常友好。 要开始使用蝗虫,请转到“安装

我的介绍

Locust是一款开源的Python性能测试框架,设计用于模拟大规模用户行为并对网站或其他系统进行负载测试。它的独特之处在于其直观的用法和高度的可定制性。

首先,Locust采用了易于理解的Python语法来定义用户行为。这意味着你可以像编写普通Python代码一样,描述一个用户在你的应用中可能会进行的操作序列。这种清晰的编程方式使得即使是非专业性能测试人员也能快速上手。

其次,Locust具备出色的扩展能力。它支持分布式测试,允许你在多台机器上运行Locust节点,形成一个强大的负载生成集群。这样的设计使得Locust能够模拟数十万级别的并发用户,帮助你准确评估系统的承载能力和潜在瓶颈。

此外,Locust基于事件驱动,并利用了gevent库实现轻量级进程(协程),从而在单个进程中支持数千并发用户。这种方式避免了传统线程模型的开销,提高了测试效率和资源利用率。

使用Locust进行性能测试的过程通常包括以下几个步骤:

  1. 环境准备:安装Python 3.6及以上版本以及Locust库。
  2. 编写用户行为:定义Locust用户类,包含用户在测试中可能执行的各种操作。
  3. 启动Locust:可以通过命令行启动Locust服务,指定测试脚本和目标主机地址。
  4. 运行测试:在Locust的Web UI中,你可以配置和控制负载测试,包括设定并发用户数、 ramp-up时间(逐步增加用户数的时间)和测试持续时间等参数。
  5. 监控和分析结果:Locust的Web UI提供了实时的测试数据和图表,帮助你监控系统性能并识别潜在的问题。

Locust安装

安装Python(3.8或更高版本)

pip3 install locust

查看是否安装成功

locust -V

编写第一个测试脚本

Locust测试本质上只是一个Python程序,它向要测试的系统发出请求。这使得它非常灵活,特别擅长实现复杂的用户流。但它也可以进行简单的测试,

from locust import HttpUser, task

class HelloWorldUser(HttpUser):
    @task
    def hello_world(self):
        self.client.get("/hello")
        self.client.get("/world")

这段代码是使用Locust库编写的Python性能测试脚本,主要目的是定义一个名为"HelloWorldUser"的用户类,该类模拟了对HTTP服务器进行两个GET请求的行为。

  1. from locust import HttpUser, task: 这一行导入了Locust库中用于HTTP性能测试的两个关键组件。HttpUser是一个基类,用于定义模拟HTTP用户行为的类;task是一个装饰器,用于标记用户类中的方法为一个性能测试任务。

  2. class HelloWorldUser(HttpUser):: 这一行定义了一个名为"HelloWorldUser"的类,它继承自HttpUser基类。这意味着这个类将模拟HTTP用户的操作。

  3. @task: 这是一个装饰器,用于标记接下来的方法hello_world为一个性能测试任务。在Locust中,每个用户在运行时会随机选择并执行标记为@task的方法。

  4. def hello_world(self):: 这一行定义了一个名为hello_world的方法,它是HelloWorldUser类中的一个任务。这个方法将在性能测试中被调用。

  5. self.client.get("/hello"): 这一行代码表示模拟的HTTP用户向服务器发送一个GET请求到"/hello"路径。self.clientHttpUser基类提供的一个属性,它封装了对HTTP服务器进行请求的操作。

  6. self.client.get("/world"): 这一行代码与上一行类似,也是模拟HTTP用户向服务器发送一个GET请求,但请求的路径为"/world"。

启动后访问:http://localhost:8089

image.png

下面的屏幕截图显示了当使用40个并发用户,以0.5个用户/秒的增长率,针对性能比较差的服务器运行测试时的情况。

image.png

找到每秒请求数(RPS)、响应时间和运行用户数

image.png

image.png

image.png

如果你看到的图表像是这样的情况:当只有大约9个用户使用服务时,响应时间就开始急剧增加。这意味着服务或者系统无法处理这么多用户的请求,这就是我们所说的遇到了瓶颈。

就像一个餐馆服务员,如果同时要照顾的餐桌太多,他可能就会忙不过来,上菜的速度就会变慢。在这个比喻中,服务员就是服务或者系统,餐桌就是用户的请求。

即使我们继续增加更多的“用户”(好比更多的顾客来到餐馆),每秒钟能处理的请求数量并没有随之增加,说明服务已经“过载”或者“饱和”,也就是服务员完全忙不过来了。

如果响应时间没有增加,那就试着继续增加用户,直到找到那个让服务“崩溃”的临界点,或者开心地发现你的服务能够应对预期的所有用户需求。

如果你在解决服务器问题或者在模拟大量用户以使系统达到极限时遇到困难,可以去看看locust官网