3. 巡检脚本编排基础:脚本编排的概念、巡检与常规压测的区别、编排的原子性要求
在容量压测自动化体系中,巡检脚本编排是连接“单点压测能力”与“持续容量保障”的关键桥梁。本章从编排概念、场景差异、原子性设计三个维度,建立巡检脚本编排的理论基础。
3.1 脚本编排的概念
脚本编排(Script Orchestration)是指将多个独立的压测/检查步骤,按照业务逻辑、时序依赖、资源约束组合成一个可自动执行的工作流。在容量巡检场景中,编排不仅仅是“串行执行”,更包含:
- 步骤依赖:前置步骤成功/失败决定后续步骤的执行路径。
- 数据传递:上游步骤的输出(如 、会话 ID)作为下游步骤的输入。
- 条件分支:根据中间指标(如响应时间、错误率)动态选择执行分支。
- 超时与重试:为每个步骤定义独立的超时阈值和重试策略。
编排 vs 脚本聚合:脚本聚合只是将多个脚本文件顺序执行,而编排具备状态感知、数据流传递、异常处理等智能调度能力。
3.2 巡检与常规压测的区别
常规压测(如容量摸底、峰值验证)与巡检脚本在目标、执行模式、数据验证上存在本质差异。下表从 7 个关键维度进行对比:
| 对比维度 | 常规压测 | 容量巡检 |
|---|---|---|
| 执行目标 | 摸清系统最大承载能力 | 验证当前容量是否满足基线 |
| 触发方式 | 人工触发 / 按需执行 | 定时触发 / 事件驱动 |
| 压测时长 | 分钟~小时级(长稳测试可达天级) | 秒~分钟级(轻量快速) |
| 并发模型 | 阶梯递增 / 固定并发 / 浪涌 | 固定低并发(通常 < 100) |
| 数据验证 | 事后分析(聚合报表) | 实时断言(逐请求校验) |
| 失败处理 | 记录错误,继续执行 | 快速失败,触发告警 |
| 资源开销 | 高(独占压测集群) | 低(复用/共享资源) |
实践建议:巡检脚本应设计为“轻量级探针”,单次巡检的请求量控制在常规压测的 1%~5%,避免巡检本身成为容量瓶颈。
3.3 编排的原子性要求
原子性(Atomicity)是巡检脚本编排的核心设计原则。一个编排步骤(Step)必须满足以下条件,才能被视为原子步骤:
- 不可拆分:步骤内部的操作要么全部成功,要么全部回滚(或标记失败)。
- 独立可测:每个原子步骤可以脱离编排独立执行,并产生可预期的结果。
- 状态自包含:步骤所需的上下文(如参数、前置数据)必须在步骤启动时已就绪,不依赖步骤执行过程中的外部状态变化。
- 超时边界清晰:每个原子步骤必须有明确的超时阈值,超时后步骤整体标记为失败。
常见反模式:将“登录 + 查询 + 下单”写在一个原子步骤中。一旦下单失败,无法区分是登录 失效还是业务逻辑异常,导致排障困难。正确的做法是将这三个操作拆分为三个原子步骤,并显式传递 和订单号。
3.4 编排原子性设计示例
以下是一个典型的容量巡检编排片段,展示原子步骤的拆分与数据传递:
# 编排定义(YAML 示例)
orchestration:
name: "order-service-capacity-check"
steps:
- id: "step-01-get-"
type: "http"
request:
method: POST
url: "/api/auth/login"
body: {"user": "perf_user", "pass": "encrypted_pass"}
assertions:
- status_code == 200
timeout: 5s
output:
: "$.response.body."
- id: "step-02-query-product"
type: "http"
depends_on: ["step-01-get-"]
request:
method: GET
url: "/api/products?page=1&size=10"
headers:
Authorization: "Bearer {{steps.step-01-get-.output.}}"
assertions:
- status_code == 200
- $.response.body.total > 0
timeout: 3s
output:
product_id: "$.response.body.items[0].id"
- id: "step-03-create-order"
type: "http"
depends_on: ["step-02-query-product"]
request:
method: POST
url: "/api/orders"
headers:
Authorization: "Bearer {{steps.step-01-get-.output.}}"
body:
productId: "{{steps.step-02-query-product.output.product_id}}"
quantity: 1
assertions:
- status_code == 201
- $.response.body.orderId != null
timeout: 5s
上述编排中,每个步骤都是原子性的:
- step-01 只负责获取 ,超时 5s,失败则整个编排终止。
- step-02 依赖 step-01 的 输出,只查询商品列表,超时 3s。
- step-03 依赖前两步的输出,只创建订单,超时 5s。
3.5 巡检编排原子性架构图
下图展示了巡检编排中原子步骤的依赖关系与数据流:
3.6 原子性设计检查清单
在实际编排开发中,建议使用以下清单对每个步骤进行原子性评审:
| 检查项 | 通过标准 | 反例 |
|---|---|---|
| 职责单一 | 步骤只完成一个业务操作 | 一个步骤同时查询用户信息和更新用户余额 |
| 超时独立 | 每个步骤有独立的超时配置 | 所有步骤共用全局超时 30s |
| 断言自洽 | 步骤的断言只校验本步骤的响应 | 在登录步骤中断言后续订单接口的返回 |
| 数据显式传递 | 步骤间数据通过编排引擎显式传递 | 步骤间通过共享全局变量隐式传递 |
| 失败隔离 | 步骤失败不影响其他步骤的上下文 | 步骤 A 失败导致步骤 B 的 缓存被清空 |
原子性收益:严格遵循原子性设计的巡检编排,在故障定位时可将排查范围缩小到单个步骤(通常 3~5 行代码),而非整个脚本(数百行代码),排障效率提升 60% 以上。