4. Locust 基础入门:安装、基本脚本结构、HttpUser 与 TaskSet 概念
Locust 是一款基于 Python 的开源负载测试工具,以其协程并发模型和可编程性在性能测试领域占据重要地位。本章将带你从零搭建 Locust 环境,理解其核心抽象——HttpUser 与 TaskSet,并掌握编写第一个压测脚本的基本结构。
4.1 环境安装与验证
Locust 依赖 Python 3.8 及以上版本,推荐使用虚拟环境隔离项目依赖。以下为安装步骤:
- 创建虚拟环境(可选但推荐):
python -m venv locust_env - 激活虚拟环境:
- Windows:
locust_env\Scripts\activate - Linux/macOS:
source locust_env/bin/activate
- Windows:
- 安装 Locust:
pip install locust - 验证安装:
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 图展示了它们之间的协作流程:
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 中控制流程跳转,避免死循环。