Locust 版本演进技术指南:从 Changelog Highlights 到核心架构变迁
【免费下载链接】locustWrite scalable load tests in plain Python 🚗💨项目地址: https://gitcode.com/gh_mirrors/lo/locust
本篇技术指南以docs/changelog.rst(Changelog Highlights)为骨架,系统梳理 Locust 从 0.4 到 2.44 各版本的核心变更,并结合当前仓库源码(如 locust/runners.py、locust/argument_parser.py、locust/contrib 等)解读这些变更背后的实现原理。读完本文,你将掌握 Locust 的架构演进脉络(master/worker 调度模型、事件系统、Web UI 现代化、各类协议扩展 User),理解当前版本命令行参数与配置项的完整语义,并能据此评估升级路径与迁移风险。
一、Changelog Highlights 是什么
docs/changelog.rst是 Locust 官方文档中的"变更日志精华"页。文档开篇即说明:2.44.2 及之后的版本不再在此文件逐版更新,读者应转向 GitHub Releases 页面与 CHANGELOG.md(该文件在本仓库中持续维护至 2.46.3)。
该文档的价值在于:它按版本回溯了 0.4 → 2.44 的关键变更,包括破坏性 API 变更、新增 User 类型、分布式模式重构、Web UI 演进、事件系统调整等,是理解 Locust 设计哲学与升级迁移的第一手资料。下面按主题重组并深度展开。
二、分布式架构的两次根本性重构
2.1 1.0 时代:master/slave 术语体系与序列化安全
在 1.0 / 1.0.1 版本中,Locust 将Locust/HttpLocust类重命名为User/HttpUser,命令行参数-c/--clients改为-u/--users,并将 master/slave 通信序列化从 pickle 切换为 msgpack(见docs/changelog.rst0.7 小节)。这一改动直接源于安全考量:pickle 反序列化可在持有内部端口访问权时执行远程代码。变更日志明确警告:使用旧版本的用户必须确保 5557/5558 端口不公开暴露,且绝不要以 root 身份运行 Locust。
当前仓库中,locust/rpc/protocol.py 的Message.serialize()/unserialize()仍延续这一安全设计,locust/rpc/zmqrpc.py 实现了基于 ZMQ 的 RPC 层。
2.2 2.0 时代:master 集中调度模型(最重要的一次破坏性变更)
docs/changelog.rst中 2.0.0 条目明确写道:
User ramp up/down 与 User 类型选择现在由master控制,而非 worker 自主决定。
这修复了此前多 worker 场景下 User 类型分布不均衡、ramp up 步进异常、以及测试中 worker 断连时无法重新分配用户等问题。与之相关的破坏性变更包括:
- User 默认权重从 10 改为 1(原默认值不合理);
test_start/test_stop事件现在也在 worker 上触发(此前仅在 master/独立模式下触发);- worker 连接时上报版本号,master 对版本差异发出警告,且拒绝 1.x 的 worker 连接(可通过发送
-1绕过版本检查); - 命令行参数
--slave/--expect-slaves更名为--worker/--expect-workers,--no-web更名为--headless。
在源码层面,这一模型体现在 locust/dispatch.py 的UsersDispatcher类:它实现了new_dispatch()、add_worker()、remove_worker()、_prepare_rebalance()等方法,并在__next__()中按迭代向各 worker 下发用户增量。而 locust/runners.py 中的MasterRunner(第 649 行起)持有WorkerNodes集合与rebalancing_enabled()逻辑,WorkerRunner(第 1224 行起)则通过heartbeat()、stats_reporter()、connect_to_master()等与 master 保持通信。从源码结构看,2.0 引入的集中调度是当前--enable-rebalancing实验特性(运行时增删 worker 自动重分配用户)的基础。
此外,locust/argument_parser.py 中仍保留了针对旧参数的友好报错:例如--expect-slaves会被拦截并提示"已更名为 --expect-workers"(第 675-680 行),--slave提示"已更名为 --worker"(第 700-705 行),--legacy-ui提示"不再支持"(第 617-624 行)。
三、User 类与任务编写模型的演进
3.1 从 Locust/TaskSet 到 User/TaskSet
1.0 版本完成了类名体系的重命名,同时允许在User类下直接用@task声明任务(此前只能在TaskSet中声明)。2.5 版本明确response.success()/.failure()若在 with 块外调用将抛异常;2.40 版本进一步让raise_for_status()考虑failure()/success()的调用结果;2.40.2 重构了 locust/clients.py 中的ResponseContextManager并修复 GC 问题。
0.6 版本曾将SubLocust替换为TaskSet,并在 1.0 移除task_set属性、改用tasks属性。当前仓库中任务模型集中在 locust/user/task.py(task装饰器、TaskSet)与 locust/user/sequential_taskset.py(SequentialTaskSet,替代 1.0 中废弃的TaskSequence/@seq_task)。
3.2 新增的 User 类型:从 FastHttpUser 到协议扩展家族
变更日志记录了大量新增 User 类型,每个都能在当前仓库 locust/contrib 目录中找到对应实现:
| 版本 | 新增能力 | 仓库源码 |
|---|---|---|
| 0.12.1 | FastHttpLocust(geventhttpclient 驱动,官方称较 HttpLocust 快 5-6 倍) | locust/contrib/fasthttp.py |
| 2.14.0 | FastHttpUser 增加rest方法,便于 REST/JSON API 测试 | 同上 |
| 2.39.0 | SocketIOUser(2.40.2 重构出独立SocketIOClient类) | locust/contrib/socketio.py |
| 2.39.0 | MilvusUser | locust/contrib/milvus.py |
| 2.41.0 | MqttUser(2.43.4 绕开 paho mqtt 的 340 连接数限制) | locust/contrib/mqtt.py |
| 2.42.0 | DNSUser | locust/contrib/dns.py |
| 2.43.4 | Qdrant 支持 | locust/contrib/qdrant.py |
| 2.34.0 | 实验性OpenAIUser及示例 | locust/contrib/oai.py |
| 2.43.4 | 将响应时间分桶提取为可覆写函数bucket_response_time | locust/stats.py |
3.3 任务调度与权重模型
- 2.27.0:使用更高效的算法计算用户分布,并支持float 权重;
- 2.25.0:修复 UserClass 权重分布的 gcd 问题;
- 2.6.0:新增
fixed_count,允许为某类用户指定精确数量而非仅按权重; - 2.38.0:新增 MarkovTaskSet(马尔可夫链任务集)。
四、事件系统:扩展 Locust 的核心机制
变更日志中事件系统的演进脉络非常清晰:
- 0.7:事件监听函数必须接收关键字参数,且推荐附加
**kw通配参数以防未来新增参数导致崩溃;request_success/request_failure的参数method/path更名为request_type/name; - 1.5.0:将
request_success/request_failure统一为单个request事件(旧事件废弃但仍可用),并新增response对象与context参数(可用于传递 username、tags 等); - 2.0.0:移除已废弃的
request_success/request_failure处理器(2.15.0 正式移除); - 2.4.0:request 事件新增
start_time与url参数(2.5.0 起 url 改为完整 URL); - 2.8.4:新增
test_stopping(测试停止前触发)与quit(获取进程退出码)事件; - 2.20.0:新增实验性的
EventHook.measure上下文管理器,自动计算响应时间并自动标记失败; - 2.30.0:新增 heartbeat 与 usage monitor 事件;
- 2.8.6:新增
cpu_warning事件,监听 CPU 过高时执行动作。
当前实现位于 locust/event.py:EventHook类提供add_listener/remove_listener/fire,其中fire(reverse=True)支持逆序执行处理器;measure()(第 56-89 行)用time.perf_counter()计算耗时并以毫秒为单位触发request事件。Events类(第 102 行起)则集中定义了request、user_error等事件及其参数文档。
1.0 版本还移除了Locust.setup/teardown与TaskSet.setup/teardown钩子,要求改用test_start/test_stop事件:
from locust import events @events.test_start.add_listener def on_test_start(**kw): print("test is starting") @events.test_stop.add_listener def on_test_stop(**kw): print("test is stopping")一个更贴近实战的用法是 2.44.0 新增的逐请求 CSV 日志组件 locust/contrib/csv_request_logger.py:CsvRequestLogger通过监听request事件将每条请求(时间戳、请求类型、名称、响应时间毫秒、响应长度、状态码、异常)逐行写入 CSV,适用于需要单点级数据而非聚合统计的后处理场景。其源码展示了事件监听的推荐姿势:在@events.init监听器中调用logger.register(environment),并在quitting事件中关闭文件。
五、Web UI 的现代化历程
Web UI 是变更日志中篇幅最大的主题之一:
- 0.8:新增 Web UI 图表(RPS、平均响应时间、模拟用户数);
- 1.0:支持
--web-auth(Basic Auth)、--tls-cert/--tls-key(HTTPS 服务)——注意当前版本中--web-auth已被--web-login取代,传旧参数会直接报错(见 locust/argument_parser.py); - 2.18.0:新增基于 React + MaterialUI + Vite 的现代 UI(当时需
--modern-ui激活); - 2.22.0:现代 UI 成为默认,移除
--modern-ui、新增--legacy-ui(后者现已被彻底移除); - 2.31.4:发布 UI NPM 包,便于自定义 UI 复用;
- 2.33.0:按回车自动在浏览器中打开 Web UI;HTML 报告文件名支持
{u}、{r}、{t}等占位符解析(见 locust/argument_parser.py 中--html参数说明); - 2.37.x 系列:host 字段校验、缺 host 警告、分布式模式下等待 worker 连接后才允许启动测试、500+ 请求名时优化
/stats/requests端点性能; - 2.42.4:Web UI 支持多选下拉;
- 2.43.4:HTML 报告与导航栏统计改用
total_rps而非current_rps。
现代 UI 源码位于 locust/webui/src,包括 SwarmForm(启动表单)、StatsTable、LogViewer 等组件。2.29.0 起 worker 日志可回传 master 并在 Log Viewer 标签页查看,这是 locust/runners.py 中WorkerRunner.logs_reporter()与 locust/web.pylogs路由协作的结果。
六、LoadTestShape 与自定义负载曲线
1.2 版本引入LoadTestShape类(当时称为"任何自定义负载形状"),并同步支持用户数下降(ramp down)、自定义百分位;2.4.1 修复 shape 模式下的统计打印;2.12.0 支持 shape 使用自定义 User 类;2.17.0 支持抽象 shape 基类,并允许 shape 复用--run-time、--spawn-rate、--users参数;2.18.4 保证两次tick()调用之间至少等待一秒;2.43.4 修复 shape 测试完成时误报 "--run-time limit reached" 的问题。
LoadTestShape的当前实现位于 locust/shape.py,其tick()返回(user_count, spawn_rate)或(user_count, spawn_rate, user_classes)元组,返回None表示结束测试。仓库 examples/custom_shape 提供了double_wave.py、stages.py、step_load.py等可运行示例。
七、命令行参数与配置体系变迁
7.1 新旧参数对照(迁移必读)
| 旧参数/旧行为 | 新参数/新行为 | 引入版本 |
|---|---|---|
--clients/-c | --users/-u | 1.0 |
--hatch-rate | --spawn-rate(--hatch-rate已废弃,2.32.6 彻底移除) | 1.2 / 2.32.6 |
--no-web | --headless | 1.0 |
--slave/--expect-slaves | --worker/--expect-workers | 1.0 |
--csv-base-name | --csv(前者仅为别名) | 1.0 |
--num-request/-n | 早已移除,改用--run-time | 0.6 时代遗留 |
--web-auth | --web-login | 2.21.0 |
--legacy-ui | 已移除(报错提示) | 2.28.0 |
--no-reset-stats(默认行为反转) | --reset-stats | 0.9 |
--modern-ui | 已成为默认 | 2.22.0 |
7.2 环境变量重命名(1.0)
为避免在 Kubernetes 中与 service/pod 名称自动注入的环境变量冲突,1.0 做了如下重命名(详见docs/changelog.rst1.0 小节):
LOCUST_MASTER→LOCUST_MODE_MASTERLOCUST_SLAVE→LOCUST_MODE_WORKERLOCUST_MASTER_PORT→LOCUST_MASTER_NODE_PORTLOCUST_MASTER_HOST→LOCUST_MASTER_NODE_HOSTCSVFILEBASE→LOCUST_CSV
当前版本中上述新环境变量均在 locust/argument_parser.py 中逐一对应(如LOCUST_MASTER_NODE_HOST对应--master-host,见第 707-712 行)。
7.3 配置文件支持
- 2.24.0:新增
pyproject.toml配置支持(此前仅支持.conf); - 1.0:新增
--config参数指定配置文件路径; - 2.42.x:修复单行
.conf文件被误判为 TOML、以及 TOML 解析器被用于.conf文件的问题; - 2.44.x:
--config-users支持以 JSON 字符串或文件指定用户配置(见 locust/argument_parser.py)。
配置解析基于 ConfigArgParse(2.37.6 起最低 1.7.1),因此支持命令行参数、环境变量、配置文件三者的统一解析,参数可在 Web UI 中显示并透传给 worker。
7.4 运行控制与统计输出类参数
- 2.19.0:新增
--processes,自动 fork 多个 worker 子进程(Windows 不可用,见 locust/argument_parser.py); - 2.37.0:新增
--json-file(2.37.1、2.37.10 两次修复其回归),将最终统计写入 JSON 文件;--json则输出到 stdout; - 2.13.0:
--stop-timeout支持时间字符串(如5m30s); - 2.2.0:新增
--autostart/--autoquit;--equal-weights忽略 locustfile 中的权重均匀分配; - 2.35.0:新增
--profile,用于对 test run 分组展示; - 2.41.0:命令行参数拼写错误时给出 "Did you mean ..." 建议;
- 2.8.0:Docker 镜像瘦身(基于 python3-slim,x64 压缩后约 95MB,2.8.1 进一步优化至约 60MB),2.40.0 起 Docker 基础镜像升至 Python 3.13,
Dockerfile位于仓库根目录。
7.5 标签过滤
1.0 版本引入@tag装饰器与--tags/-T、--exclude-tags/-E参数;2.6.0 起这两个参数会透传给 worker。当前参数说明见 locust/argument_parser.py。
八、统计、报告与可观测性
8.1 统计系统演进
- 0.7:
RequestStats重构,拆分出单条目的StatsEntry; - 0.13:响应时间统计 CSV 增加 p99.9 与 p99.99;统计表末行由 "Total" 更名为 "Aggregated";
- 1.4.2:新增
--html选项保存 HTML 报告; - 2.15.1:新增
PERCENTILES_TO_CHART参数配置响应时间图; - 2.30.0:UI 总平均响应时间替换为 50 分位(原 avg 有 bug);
- 2.44.0:失败统计新增 first seen / last seen 时间戳。
统计核心实现位于 locust/stats.py,包括StatsEntry.log()、percentile()、serialize()以及StatsCSV的 CSV 写出(requests/failures/exceptions/history 四类文件)。
8.2 OpenTelemetry 与日志
- 2.42.4:新增 OpenTelemetry 支持;2.42.5 增加启用时日志;2.43.4 发布含 OTEL 依赖的
locust-otelDocker 镜像;2.44.1 为 OTEL 增加日志支持并更新 resource。
实现位于 locust/opentelemetry.py,命令行开关为--otel(环境变量LOCUST_ENABLE_OPENTELEMETRY,见 locust/argument_parser.py),仓库另有 Dockerfile.otel 供参考。
九、分布式、进程与平台支持的时间线
- 0.13.5:多 slave 连接问题修复;
- 2.4.2:新增
--expect-workers-max-wait(master 等待 worker 连接的超时上限,默认永久等待);追踪 worker 内存使用; - 2.19.0:master 消失过久时 worker 自动关闭;
- 2.20.1:master/worker 的 ZMQ 连接支持 IPv6;
- 2.32.0:显式支持 Python 3.13,并处理 IPv6 可用性判断(尤其针对 EKS);
- 2.41.6:正式支持 Python 3.14。
Python 版本支持的时间线为:0.14 放弃 Python 2 与 3.5 → 2.26.0 放弃 3.8 → 2.34.1 放弃 3.9 → 2.46.1 放弃 3.10(见 CHANGELOG.md)。
十、安全与稳定性要点
- 0.7:msgpack 替换 pickle 序列化,杜绝远程代码执行;
- 1.3.2:修复 Web UI XSS 漏洞(官方注明影响有限,因为 UI 不应对外暴露);
- 1.0.2 / 2.37.12:检测并尝试自动提升
RLIMIT_NOFILE打开文件数上限; - 2.0.0:版本不匹配的 worker 将被拒绝连接;
- 2.32.5:
init事件处理器异常视为致命错误;FastHttpUser 修复 SSL 证书加载性能问题(仅加载一次,2.43.0 在 requests>=2.32.5 下重实现); - 2.31.6:
LocalRunner增加worker_count = 1与MasterRunner对齐。
十一、升级迁移清单(基于变更日志归纳)
若要从旧版本升级,重点核对以下破坏性变更:
- 2.0+:分布式模式下调度权已归 master,务必统一 master 与所有 worker 的版本;
- 1.0+:
Locust→User、HttpLocust→HttpUser、--clients→--users、--no-web→--headless;环境变量按 1.0 小节重命名; - 2.15.0:
request_success/request_failure处理器已彻底移除,统一迁移到request事件; - 2.28.0:旧版 UI 已不可用;
- 2.32.6:
--hatch-rate已移除; - 2.34.1+:Python 3.9/3.10 用户需先升级 Python;
- 事件监听函数一律使用关键字参数并带
**kw,防止未来事件签名扩展导致崩溃。
结语
docs/changelog.rst浓缩了 Locust 十余年的演进史:从单一进程脚本到 master 集中调度的分布式压测平台,从requests到 geventhttpclient 的性能路径,从 pickle 到 msgpack 的安全加固,从 Flask 模板 UI 到 React 现代 UI,以及覆盖 HTTP、gRPC、MQTT、MongoDB、Milvus、Qdrant、PostgreSQL、Socket.IO、OpenAI、DNS 等协议的用户类家族。理解这些变更,不仅能帮你安全地完成版本升级,更能让你在阅读 locust 源码、编写自定义扩展(事件、User、shape、dispatcher)时快速定位设计意图。对于 2.44.2 之后的更新,请以仓库根目录的 CHANGELOG.md 为准。
【免费下载链接】locustWrite scalable load tests in plain Python 🚗💨项目地址: https://gitcode.com/gh_mirrors/lo/locust
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考