4. Locust 基础入门:安装、基本脚本结构、HttpUser 与 TaskSet 概念

Locust 是一款基于 Python 的开源负载测试工具,以其协程并发模型和可编程性在性能测试领域占据重要地位。本章将带你从零搭建 Locust 环境,理解其核心抽象——HttpUser 与 TaskSet,并掌握编写第一个压测脚本的基本结构。

4.1 环境安装与验证

Locust 依赖 Python 3.8 及以上版本,推荐使用虚拟环境隔离项目依赖。以下为安装步骤:

  1. 创建虚拟环境(可选但推荐):python -m venv locust_env
  2. 激活虚拟环境:
    • Windows: locust_env\Scripts\activate
    • Linux/macOS: source locust_env/bin/activate
  3. 安装 Locust:pip install locust
  4. 验证安装:locust --version
版本确认:建议锁定 Locust 2.x 系列(如 2.31.0),避免因 API 变更导致脚本不兼容。安装后可通过 pip show locust 查看详细版本信息。

4.2 基本脚本结构

一个最小化的 Locust 脚本通常包含以下三个要素:

组件 作用 必须性
HttpUser 模拟虚拟用户,持有 HTTP 客户端 必须
TaskSet 定义用户执行的任务序列 推荐
@task 装饰器 标记任务方法,可设置权重 必须(至少一个)

以下是一个完整的入门脚本示例:

from locust import HttpUser, TaskSet, task, between

class UserBehavior(TaskSet):
    """定义用户行为:访问首页和关于页面"""

    @task(3)  # 权重为3,表示相对更频繁执行
    def visit_home(self):
        self.client.get("/")

    @task(1)  # 权重为1
    def visit_about(self):
        self.client.get("/about")

class WebsiteUser(HttpUser):
    """模拟用户类,关联 TaskSet 并设置等待时间"""
    tasks = [UserBehavior]
    wait_time = between(1, 5)  # 每个任务执行后等待1~5秒
执行方式:将上述代码保存为 locustfile.py,在终端运行 locust 命令(默认读取当前目录下的 locustfile.py)。然后访问 http://localhost:8089 打开 Web UI,设置并发用户数和 spawn rate 即可启动压测。

4.3 HttpUser 核心概念

HttpUser 是 Locust 中模拟真实 HTTP 客户端的基类。它自动为每个虚拟用户维护一个 client 属性,该属性是 HttpSession 实例,支持 GET、POST、PUT、DELETE 等常用方法,并自动记录请求成功/失败状态、响应时间等指标。

关键属性与方法:

  • client:HTTP 客户端,用法类似 requests 库,支持 headers、cookies、params、json 等参数。
  • wait_time:定义任务执行间隔,常用 between(min, max) 或 constant(sec)。
  • host:目标服务器地址,可在 Web UI 或命令行中指定。
  • weight:当有多个 User 类时,用于分配用户比例。
注意:不要在 HttpUser 的 __init__ 方法中执行耗时操作,因为每个虚拟用户都会实例化一次。初始化逻辑应放在 on_start 方法中。

4.4 TaskSet 概念与用法

TaskSet 是 Locust 中组织任务的核心容器。它允许你将一组相关的用户操作封装在一起,支持嵌套、权重控制和条件执行。

TaskSet 的核心特性:

特性 说明 示例
@task 装饰器 标记方法为可执行任务,可传入权重整数 @task(3)
嵌套 TaskSet 一个 TaskSet 可以包含另一个 TaskSet,模拟多级行为 tasks = [LoginTaskSet, BrowseTaskSet]
on_start / on_stop 用户开始/结束任务集时自动执行的方法 用于登录、获取 等前置操作
interrupt() 从嵌套 TaskSet 中跳出,返回父级 TaskSet 用于退出登录子流程

嵌套 TaskSet 示例:

from locust import HttpUser, TaskSet, task, between

class LoginTasks(TaskSet):
    @task
    def login(self):
        self.client.post("/login", json={"user": "test", "pass": "123"})
        # 登录成功后跳转到浏览任务
        self.interrupt()  # 返回父级 TaskSet

class BrowseTasks(TaskSet):
    @task(2)
    def view_item(self):
        self.client.get("/item/1")

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

class WebsiteUser(HttpUser):
    tasks = [LoginTasks, BrowseTasks]
    wait_time = between(2, 5)

4.5 HttpUser 与 TaskSet 的关系

理解两者的关系是编写复杂脚本的基础。以下 SVG 图展示了它们之间的协作流程:

HttpUser 与 TaskSet 协作关系图 HttpUser 与 TaskSet 协作流程 HttpUser 模拟虚拟用户 关联 TaskSet 任务容器 包含 @task 任务方法 执行流程: 1. Locust 根据 HttpUser 生成虚拟用户实例 2. 每个用户从关联的 TaskSet 中随机选取 @task 方法执行 3. 执行完毕后按 wait_time 等待,然后重复选取下一个任务 关键点: HttpUser 是“人”,TaskSet 是“行为剧本”,@task 是“具体动作”。 一个 HttpUser 可以关联多个 TaskSet,通过权重控制行为比例,实现复杂用户模拟。

4.6 常用配置与命令行参数

Locust 提供了丰富的命令行参数,方便在 CI/CD 或 Runbook 中无头运行。以下为常用参数:

参数 说明 示例
-u / --users 模拟的并发用户数 --users 100
-r / --spawn-rate 每秒启动的用户数 --spawn-rate 10
-t / --run-time 压测持续时间(如 1h30m) --run-time 10m
--headless 无 Web UI 模式,适合自动化 --headless
--host 目标服务器地址 --host https://api.example.com
--csv 导出 CSV 格式的压测报告 --csv result

无头模式运行示例:

locust -f locustfile.py --headless -u 50 -r 5 --run-time 5m --host https://test.api.com --csv report

4.7 常见问题与避坑指南

  • TaskSet 未执行:检查 HttpUser 的 tasks 属性是否正确赋值,且至少有一个 @task 方法。
  • 请求超时:Locust 默认超时时间为 60 秒,可通过 client.get(url, timeout=10) 自定义。
  • Cookie 未保持:HttpSession 自动管理 Cookie,无需手动处理;若需跨用户隔离,请使用 client.cookies.clear()。
  • 权重不生效:权重仅在同一个 TaskSet 内的任务之间生效;不同 TaskSet 之间的选择概率由 tasks 列表中的元素数量决定。
最佳实践:将登录等前置操作放在 on_start 方法中,确保每个虚拟用户开始执行任务前已完成认证。同时,使用 self.interrupt() 在嵌套 TaskSet 中控制流程跳转,避免死循环。