一、为什么选择 Locust?
在传统性能测试领域,JMeter 长期占据主导地位,但在面对需要高度定制业务逻辑、动态签名计算或复杂状态机轮询的高并发压测场景时,纯代码驱动的性能工具往往展现出更高的工程灵活性。
Locust 是一款用 Python 编写的开源负载测试工具,核心优势体现在:
- 常规代码定义用户行为:无需配置笨重的 XML 或陷入特定 UI 界面,完全使用 Python 标准语法编写测试逻辑。
- 底层基于 gevent 协程:单个线程内利用绿色线程(Greenlet)处理非阻塞异步 I/O,单台压测机即可模拟数千个高并发虚拟用户,内存开销极低。
- 原生支持分布式扩展:天然支持 Master / Worker 架构,能横向扩展到多台机器分布式压测。
- 灵活的协议扩展性:不仅支持 HTTP/HTTPS,只需在客户端提供 Python Socket/TCP/gRPC 驱动,即可测试任何自定义通信协议。
二、Locust 核心架构与运行模型
Locust 的分布式拓扑包含两个核心节点角色:
text
┌────────────────────────────────────────────────────────┐
│ Master 协调控制节点 │
│ • 启动/停止负载测试 • 分发并发任务与参数 │
│ • 汇总并实时聚合统计数据 • 提供 Web UI 监控仪表盘 │
└───────────────▲────────────────────────▲───────────────┘
│ 心跳与聚合指标 │ 指令下发
┌───────┴────────┐ ┌───────┴────────┐
│ Worker 节点 1 │ │ Worker 节点 2 │
│ (gevent 协程池) │ │ (gevent 协程池) │
└────────────────┘ └────────────────┘- Master 节点:负责集中控制、分发任务以及接收所有 Worker 上报的指标数据,本身不产生实际压测流量。
- Worker 节点:实际产生并发负载的执行机,每台 Worker 根据分配的虚拟用户数启动协程并发发送请求。
三、测试生命周期与核心 API
在编写 Locust 测试脚本时,通常围绕以下三个核心类展开:
1. HttpUser 与并发用户定义
HttpUser 为每个模拟用户注入一个具备会话保持能力(类似 requests.Session)的 client 对象:
python
from locust import HttpUser, task, between
class WebPortalUser(HttpUser):
# 模拟用户在每个任务执行间隔思考 1 到 3 秒
wait_time = between(1, 3)
# 目标压测服务基地址(也可通过命令行 --host 动态注入)
host = "https://api.example.com"2. @task 权重控制与任务编排
通过 @task(weight) 可以精准控制不同业务接口的并发流量配比:
python
@task(3)
def view_device_list(self):
"""权重为 3:查询设备列表(高频读操作)"""
self.client.get("/api/v1/devices", headers={"Authorization": "Bearer token"})
@task(1)
def export_report(self):
"""权重为 1:导出报表(低频重计算操作)"""
self.client.post("/api/v1/reports/export", json={"type": "daily"})3. TaskSet 复杂业务流建模
针对带有前后顺序依赖的多步业务(如:登录 -> 检索设备 -> 下发控制指令 -> 登出),可使用 TaskSet 进行分级封装:
python
from locust import SequentialTaskSet, task
class DeviceInspectionFlow(SequentialTaskSet):
@task
def step1_login(self):
res = self.client.post("/login", json={"user": "tester", "pwd": "123"})
self.token = res.json().get("token")
@task
def step2_check_metrics(self):
self.client.get("/metrics", headers={"token": self.token})
@task
def step3_finish(self):
self.interrupt() # 完成当前流程,返回上一级四、事件钩子(EventHook)深度定制
Locust 提供了丰富的生命周期钩子,用于在测试的不同阶段执行初始化或指标清理:
test_start:整个测试启动时触发(可用于在 Master 上初始化测试数据);test_stop:测试结束时触发(可用于清理脏数据并归档报表);request:每个 HTTP 请求完成时触发(可用于将响应耗时同步推送到外部监控系统)。
python
from locust import events
@events.test_start.add_listener
def on_test_start(environment, **kwargs):
print("压测集群已就绪,开始初始化基础数据...")
@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
print("压测执行完毕,开始汇总执行结果...")五、常用命令行运行规范
在持续集成流水线或生产测试中,通常采用 Headless(无界面)模式执行:
bash
# 单机无界面自动化压测:
# -u 500: 总共模拟 500 个虚拟用户
# -r 50: 每秒启动(梯形加压)50 个用户
# -t 10m: 持续运行 10 分钟
# --html: 自动生成完整 HTML 格式测试报告
locust -f load_test.py --headless -u 500 -r 50 -t 10m --html=report.html分布式集群启动方式:
bash
# 在主节点启动 Master
locust -f load_test.py --master
# 在执行机上启动 Worker(可根据 CPU 核数启动多个 Worker 进程)
locust -f load_test.py --worker --master-host=127.0.0.1