系列12-接口压测怎么做成平台能力?自研 httpx 引擎、分布式 Worker 与 Locust 选型对照

系列12-接口压测怎么做成平台能力?自研 httpx 引擎、分布式 Worker 与 Locust 选型对照

团队做性能测试,常见两条路:

  1. Locust / 自写脚本 :灵活,但 URL/Body/Token 与接口回归 两套维护,报告散落本地 HTML
  2. JMeter GUI:功能全,但 XML 难维护,CI 集成重

BrickCore 选第三条:复用接口自动化用例(ApiTestCase)+ asyncio/httpx 自研压测引擎 ,可选 Perf Worker 水平加并发。

需要先说清一点:平台 没有嵌入 Locust ,Docker 镜像也不带 Locust 依赖;执行层借鉴 Locust 的 并发用户 / Ramp-up / 分布式 Worker 产品思路,HTTP 请求与变量替换与 run_single_case 同源build_perf_request → httpx)。


演示与源码

地址
功能演示 http://43.142.83.156/showcase/ (性能测试相关说明见文档中心;平台 admin / BrickCore123456)
开源仓库 https://gitee.com/BanZhuanKeOrz/BrickCore

线上路径:性能测试 → 场景管理 / 执行机 / 执行记录 。Worker 推荐 BrickCoreRunner v1.3.14+ 选「压测执行机」角色上线。


一、平台化压测要解决什么

脚本压测痛点 平台化做法
Swagger 已导入,压测又要抄一遍 URL 场景 引用已有 ApiTestCase
测试/预发 Host、Token 各写各的 Environment + Token 授权 + merge_execution_variables
报告不在统一看板 PerfRecord 落库 + 曲线 + 多轮对比
单机并发不够 Perf Worker 注册、按比例拆并发
大模型 SSE 接口只看总 RT stream_burst + qa_sse_v1 阶段指标

二、架构一图读懂

复制代码
PerfScene(场景:scene_items + config + csv)
    ↓ POST /perf/exec/{scene_id}?use_workers=
PerfRecord(config_snapshot 不可变快照)
    ↓ run_perf_scene(BackgroundTasks)
┌─────────────────┬──────────────────────────┐
│ 本机 asyncio     │ 分布式 use_workers=true   │
│ Backend httpx   │ distribute_concurrent    │
│ 虚拟用户协程池   │ → Perf Worker(perf_worker)│
└─────────────────┴──────────────────────────┘
    ↓ 秒级聚合 time_series_data
报告:QPS / P95 / error_rate / case_aggregations / phase_metrics

与 UI Runner 分工 :Perf Worker 只跑 HTTP 压测;UI Runner 跑 Playwright,队列协议不同(系列09)。


三、数据模型

复制代码
PerfScene
  ├─ scene_items: [{case_id, weight, delay_ms}, ...]
  ├─ config: {mode, concurrent_users, ramp_up_seconds, ...}
  └─ csv_data + csv_config

PerfRecord(一次执行)
  ├─ config_snapshot / scene_items_snapshot
  ├─ total_requests, qps, p95, error_rate, time_series_data
  ├─ case_aggregations(接口维度)
  ├─ phase_metrics / request_details(SSE 场景)
  └─ distribution_info(分布式 Worker 分配)

PerfWorker
  ├─ register / heartbeat / unregister
  ├─ max_concurrent
  └─ project_id(须与场景项目一致)

快照设计 :场景事后被改,历史报告仍对应 当时 的配置与用例列表------发版对比靠 record_id,不靠「还记得上次参数」。


四、五种压测模式

mode 说明 典型场景
fixed 固定并发 + 持续时长(秒) 稳态容量验证
loop 固定并发 + 每用户循环 N 次 固定请求总量
stepping 多阶段递增并发与时长 梯度加压、找拐点
stream_burst 每虚拟用户 1 次 SSE 流式请求,采集问答各阶段耗时 大模型 / 流式 API
journey_fixed / journey_loop 业务链路:多阶段顺序执行,步骤间 extractors 传参 登录→业务接口

固定/循环/梯度模式还可勾选 流式问答 :在持续压测中对指定用例走 SSE 引擎(use_stream_execution)。

场景项示例 (权重 + 思考时间,概念对齐 Locust @task(weight) + between):

json 复制代码
[
  {"case_id": 101, "weight": 3, "delay_ms": 500},
  {"case_id": 102, "weight": 1, "delay_ms": 0}
]

配置示例

json 复制代码
{
  "mode": "fixed",
  "concurrent_users": 50,
  "ramp_up_seconds": 10,
  "duration_seconds": 120,
  "error_rate_threshold": 5,
  "request_detail_level": "brief"
}

error_rate_threshold:错误率 连续 3 秒 超阈值自动停压(workers.pyERROR_RATE_AUTO_STOP_MSG)。


五、执行链路(源码)

5.1 启动

python 复制代码
# routers/perf/exec.py --- start_perf
record = await PerfRecord.create(
    scene_id=scene_id, status="pending", trigger_type="manual",
    config_snapshot=config,
    scene_items_snapshot=scene.scene_items,
)
background_tasks.add_task(run_perf_scene, record.id, use_workers)

5.2 run_perf_scene 核心步骤

  1. 快照 ,解析 env_id、Host(可 target_host 覆盖环境)
  2. Host 连通性探测 (HEAD),失败则 record.status=failed
  3. 预加载 ApiTestCase + ApiDefinitionmerge_execution_variables 合并项目/环境变量
  4. 构建 scene_items_for_worker(含 merged headers/body,减少 Worker 侧查库)
  5. 分支:本机 asyncio分布式 Worker

5.3 本机:虚拟用户 + 信号量

python 复制代码
# _perf_worker_fixed:random.choices(case_pool, weights=...) 按 weight 选接口
async with sem:  # sem = concurrent_users
    result = await _execute_perf_case_request(case, env, target_host, client, csv_row, ...)
    if delay_ms > 0:
        await asyncio.sleep(delay_ms / 1000)

_execute_perf_case_request 走 httpx,成功判定:status < 500 且断言通过(与功能回归同源断言逻辑)。

5.4 分布式:并发拆分

python 复制代码
# routers/perf/workers.py --- distribute_concurrent
# 按各 Worker max_concurrent 比例分配,且不超过单节点上限
assignments = distribute_concurrent(total_concurrent, workers)

Worker 侧引擎与 Backend 同一套 runner/perf_worker.py(BrickCoreRunner 内置或命令行启动),秒级指标 POST /workers/{record_id}/report,结束后 finalize 汇总。

硬约束journey_* 模式若含阶段 sync_before 屏障不支持分布式 ------引擎会直接 failed 并提示改单机执行(journey_has_sync_barrier 校验)。


六、复用接口用例:变量与断言

压测不另写 locustfile,请求构建走 build_perf_request

python 复制代码
all_variables = ensure_dt_cache(await merge_execution_variables(case.project_id, env.id))
# + csv_row 列 → ${{username}}
# + journey 步骤间 session_variables(extractors)
method, url, headers, params, body, timeout, body_type = ...
能力 说明
${``{env_var}} 与接口回归同一套替换
${``{df:标签}} / ${``{dt:...}} 数据工厂、插入工具
CSV 列 ${``{username}}
断言 压测仍执行;失败计入 error_rate(可弱化非关键断言)

实操 :压测前用 接口用例单跑 确认 Host、Token、Body;再挂到场景里加权。


七、CSV 参数化

csv_data 存 JSON 数组,csv_config.strategy

strategy 行为
round_robin 虚拟用户轮询各行
unique 每用户绑定一行(用户数 ≤ 行数)
random 随机取行

分布式下 get_next_csv_row(..., worker_id, total_workers) 避免多 Worker 抢同一行。


八、Perf Worker 部署(推荐 BrickCoreRunner)

8.1 客户端方式(推荐)

  1. 安装 BrickCoreRunner v1.3.14+
  2. 登录 → 执行角色 仅压测UI + 压测
  3. 选择 压测项目 (与平台顶部项目 ID 一致)→ 上线
  4. 性能测试 → 执行机 确认 在线
  5. 场景执行勾选 使用分布式 Worker

客户端会话区 + runner/logs/perf_worker.log 可看秒级 QPS/RT;下线自动 unregister,不必等心跳超时。

8.2 命令行(CI / 高级)

bash 复制代码
cd runner
python perf_worker.py --master http://你的平台地址 \
  --token my-local-token \
  --name "压测机-01" \
  --max-concurrent 200 \
  --project-id 当前项目ID

生产环境浏览器访问一般为 80 端口(Nginx)--master 不要写 :8000

8.3 何时勾选 Worker

场景 建议
小并发冒烟、链路调试 不勾选,Backend 本机执行
高并发、多机叠加 QPS 勾选 Worker
无在线 Worker 自动 降级本机(cron 同理)

九、流式 / SSE 与大模型压测

stream_burst 模式 + stream_profile.parser_id(默认 qa_sse_v1):

  • 每用户 一次 完整 SSE 会话
  • 采集:首字时间、思考耗时、各阶段 RTphase_metrics
  • 报告支持 SSE 阶段汇总 、流式明细懒加载、导出 Excel
  • request_detail_level=detailed 可保留成功 trace,不影响 QPS/RT 聚合

固定/循环/梯度模式也可对指定用例勾选流式执行,适合「混合流量里夹 SSE 接口」。


十、业务链路(Journey)

journey_fixed / journey_loop:多 phase 顺序/并行,步骤间 extractors → session_variables,等价压测版「登录→下单」:

json 复制代码
{
  "mode": "journey_fixed",
  "concurrent_users": 20,
  "duration_seconds": 300,
  "journey": {
    "phases": [
      {
        "name": "登录",
        "execution": "serial",
        "steps": [{"case_id": 101, "delay_ms": 0}]
      },
      {
        "name": "下单",
        "execution": "serial",
        "sync_before": false,
        "steps": [{"case_id": 102, "delay_ms": 200}]
      }
    ]
  }
}

sync_before: true 为阶段屏障(全链路用户齐步走)------仅单机 ;分布式请关闭或改 journey_fixed 单机压测。


十一、报告读什么

指标 说明 发版决策
QPS / 成功 QPS 吞吐 是否达 SLA
avg / P90 / P95 / P99 延迟分布 长尾是否恶化
error_rate 失败占比 对照阈值、自动停压
time_series_data 秒级曲线 是否「越压越慢」
case_aggregations 分接口统计 定位慢接口

分位采样说明 :接口维度 P90/P95/P99 基于 最多 5000 条 RT 样本(蓄水池采样,MAX_CASE_RT_SAMPLES);总请求数、QPS、错误率、Min/Max 仍统计全量。超大规模压测时分位为近似值,报告页有说明。

支持 多 record 对比 、HTML 导出、完成后 邮件/钉钉/企微 推送(maybe_auto_push_perf_report)。


十二、与 Locust 选型对照

维度 Locust 脚本 BrickCore 平台压测
接口定义 locustfile 手写 引用 ApiTestCase
环境切换 改代码/环境变量 env_id
分布式 master/worker Perf Worker + 比例分配
权重/间隔 @task / between weight / delay_ms
SSE 阶段 需自写解析 stream_burst + qa_sse_v1
报告 本地 HTML 落库 + 曲线 + 对比 + 通知
依赖 Locust asyncio + httpx(镜像更轻)

外部仍有 Locust 脚本时,结果需自行对接;平台侧重 与接口资产、定时任务、看板一体


十三、发版前压测 SOP

  1. 场景 :核心 3~5 个接口,weight 按生产流量比例
  2. 环境 :独立压测环境,勿误打生产
  3. 冒烟:10 并发 × 60s 本机验证用例与 CSV
  4. 加压stepping 或提高 concurrent_users,勾选 Worker
  5. 阈值 :设 error_rate_threshold(如 5%)
  6. 对比 :与同场景上一版 record_id 比 P95、error_rate
  7. 归档 :评审贴 record 链接;可选 定时压测PerfCronJob + use_workers

十四、常见排错

现象 原因 处理
Host 不可达 env.host 错 / 网络 检查环境;exec 前有 HEAD 探测
Worker 不分配 无在线 / project_id 不一致 执行机页看 heartbeat;Runner 选对项目
分布式启动 failed journey + sync_before 关屏障或单机
error_rate 100% Token/Body 错 接口用例单跑通过再压
QPS 很低 delay_ms 大 / 断言过重 / 瓶颈在被测方 调参;看 time_series
与 Locust 数值差 连接复用、模型不同 趋势 与相对对比,不必抠绝对值一致
分位与 Locust 差很多 5000 样本蓄水池 看全量 QPS/错误率;知悉分位为近似

十五、小结

  1. 平台压测 = ApiTestCase 资产 + asyncio/httpx 自研引擎,不是嵌入 Locust。
  2. 五种模式 覆盖稳态、梯度、SSE、业务链路;快照保证报告可追溯。
  3. Perf Worker 与 Backend 同引擎distribute_concurrent 按容量比例拆并发。
  4. CSV + 变量合并 与接口回归同源;报告支持对比、SSE 阶段、自动停压与通知。

附录 A:源码文件索引

顺序 文件 关注点
1 models/perf.py PerfScene / PerfRecord / PerfWorker / PerfCronJob
2 routers/perf/exec.py start_perfrun_perf_scene、各 mode worker
3 routers/perf/workers.py register、distribute_concurrent、秒级上报
4 modules/perf/perf_journey.py 链路编排、sync 屏障
5 modules/stream_phase/ SSE 解析、stream_burst
6 runner/perf_worker.py 分布式 Worker 执行引擎
7 routers/perf/cron.py 定时压测、use_workers 降级

选型背景docs/ROADMAP.md):零 Locust 依赖、直接复用接口用例变量/断言,Docker 部署更轻。


支持与交流

相关推荐
2603_9552797011 小时前
Cursor + GitOps:自动化运维新姿势
运维·自动化
workflower12 小时前
设备单元级(L1)实施路径
人工智能·线性代数·矩阵·机器人·开源
ai_coder_ai12 小时前
编写自动化脚本,在自己后端服务中使用Open Api进行设备相关操作
java·运维·自动化
格子软件13 小时前
2026年GEO贴牌代理:分布式多级分账状态机源码深度解构
java·vue.js·分布式·vue·geo
菩提小狗14 小时前
每日极客日报 · 2026年07月04日
ai·开源·极客日报·it热点·技术资讯
搬砖柯16 小时前
系列10-接口/UI 自动化怎么验落库?数据工厂与数据库断言实践
数据库·测试工具·ui·开源·自动化
一知半解仙16 小时前
2026年彻底免费的辅助编程Agent大模型汇总
开发语言·人工智能·开源
北邮刘老师17 小时前
国标配套开源实现再升级!AIP智能体互联开源项目v2.1.0正式发布
人工智能·开源·大模型·智能体·智能体互联网
LT101579744418 小时前
2026年在线兼容性测试工具推荐|零部署网页 / APP / 小程序实测对比
测试工具·小程序