第 15 章 · 作为库使用
本章目标:不通过
locust命令行,而是以 Python 库方式编程式启动压测,掌握 Environment/Runner 模型、嵌入 pytest 与 CI 流水线的方法。
15.1 Environment 与 Runner 模型
Locust 的命令行工具本质上是以下核心类的封装:
Environment(环境)
├── user_classes → 注册的 User 类列表
├── events → 事件系统
├── runner → Runner 实例(控制启停)
│ └── greenlet → 运行协程
└── web_ui → Web UI 服务(可选)编程式启动的最小代码:
from locust.env import Environment
from my_locustfile import MyTestUser
# 1. 创建 Environment,注册 User 类
env = Environment(user_classes=[MyTestUser])
# 2. 创建本地 Runner
env.create_local_runner()
# 3. 启动压测:500 个用户,每秒孵化 20 个
env.runner.start(5000, spawn_rate=20)
# 4. 阻塞等待压测完成
env.runner.greenlet.join()15.2 控制压测生命周期
Runner 对象提供了完整的生命周期控制:
import time
from locust.env import Environment
from my_locustfile import MyTestUser
env = Environment(user_classes=[MyTestUser])
env.create_local_runner()
# 阶梯加压:逐步增加并发用户数
for users in [10, 50, 100, 200]:
env.runner.start(users, spawn_rate=10)
time.sleep(60) # 每级持续 60 秒
# 手动停止
env.runner.quit()带超时的自动停止
import gevent
def stop_after(seconds: int):
gevent.sleep(seconds)
print(f"{seconds}s 到期,自动停止")
env.runner.quit()
# 5 分钟后自动结束
gevent.spawn(stop_after, 300)
env.runner.start(1000, spawn_rate=50)
env.runner.greenlet.join()
print("压测结束")15.3 编程式访问统计数据
不用 Web UI,直接从代码中读取实时统计:
import time
from locust.env import Environment
from my_locustfile import MyTestUser
env = Environment(user_classes=[MyTestUser])
env.create_local_runner()
env.runner.start(100, spawn_rate=20)
# 每 10 秒打印一次统计摘要
for _ in range(6):
time.sleep(10)
stats = env.stats
total = stats.total
print(f"RPS: {total.current_rps:.1f} | "
f"Avg: {total.avg_response_time:.0f}ms | "
f"P95: {total.get_response_time_percentile(0.95):.0f}ms | "
f"Failures: {total.num_failures}")
env.runner.quit()常用统计属性:
| 属性 | 说明 |
|---|---|
stats.total.current_rps | 当前每秒请求数 |
stats.total.avg_response_time | 平均响应时间(ms) |
stats.total.get_response_time_percentile(0.95) | P95 响应时间 |
stats.total.num_requests | 总请求数 |
stats.total.num_failures | 总失败数 |
stats.errors | 错误详情字典 |
15.4 嵌入 pytest:性能回归测试
将轻量级性能检查嵌入单元测试流程——每次 CI 构建自动验证关键接口的响应时间:
# test_perf.py
import pytest
from locust.env import Environment
from locust_stats import check_thresholds # 自定义断言辅助
from my_locustfile import ApiUser
@pytest.fixture(scope="module")
def perf_env():
"""创建并清理 Locust 环境"""
env = Environment(user_classes=[ApiUser])
env.create_local_runner()
yield env
env.runner.quit()
class TestAPIPerformance:
def test_home_page_under_200ms(self, perf_env):
"""首页平均响应 < 200ms"""
perf_env.runner.start(20, spawn_rate=20)
time.sleep(30) # 运行 30 秒收集数据
avg = perf_env.stats.total.avg_response_time
assert avg < 200, f"首页平均响应 {avg:.0f}ms 超过阈值 200ms"
def test_error_rate_below_1pct(self, perf_env):
"""错误率 < 1%"""
total = perf_env.stats.total
if total.num_requests > 0:
rate = total.num_failures / total.num_requests
assert rate < 0.01, f"错误率 {rate:.2%} 超过阈值 1%"注意事项
CI 中跑性能测试要固定资源规格(同一台 runner、同样的网络条件),否则结果不可比。建议在独立的专用节点上运行。
15.5 启用 Web UI 的编程模式
编程式运行时也可以开启 Web UI 来监控进度:
env = Environment(user_classes=[MyTestUser])
env.create_local_runner()
# 同时启动 Web UI
env.create_web_ui()
env.runner.start(500, spawn_rate=25)
env.web_ui.greenlet.join() # 阻塞直到手动停止或进程退出访问 http://localhost:8089 可实时查看图表和统计数据。
Worker 不适合编程式创建
官方文档明确指出:虽然技术上可以通过 create_worker_runner() 创建 worker,但这几乎从不合理——每个 worker 必须是独立 Python 进程。分布式 worker 请使用标准 CLI 命令 locust --worker ...。
15.6 跳过 Monkey-Patching
在某些场景下(如在 Jupyter Notebook 中调试),monkey-patching 可能引发冲突。可以在导入 locust 前设置环境变量跳过:
import os
os.environ["LOCUST_SKIP_MONKEY_PATCH"] = "1"
# 然后再导入 locust
from locust import User, task性能影响
跳过 monkey-patching 后,所有 I/O 操作变为阻塞式,单进程只能串行执行任务。仅用于调试场景。
本章小结
Environment→create_local_runner()→runner.start(users, spawn_rate)三步启动压测;env.stats提供编程式访问 RPS、响应时间分位数、错误率等数据;- 将轻量性能检查嵌入 pytest fixture,实现 CI 自动化性能回归;
- Web UI 可通过
create_web_ui()在编程模式下启用; - 分布式 worker 请始终使用 CLI 启动。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. 编程式启动 Locust 压测的第一个步骤是什么?
2. 如何获取当前的 P95 响应时间?
3. 为什么不应该用 create_worker_runner() 创建 worker?
4. 在什么情况下应该设置 LOCUST_SKIP_MONKEY_PATCH 环境变量?
🛠️ 动手实践
- 用编程方式编写一个阶梯加压脚本:从 10 用户开始,每分钟翻倍,直到达到 500 用户。
- 将一个 API 的 P99 响应时间检查嵌入 pytest 测试,并在本地运行验证。
- 尝试在编程模式中同时启用 Web UI 和自定义统计回调,观察两者是否正常工作。
下一章学习 插件与扩展 生态,定制属于你的 Locust。