4. 自定义检查点(Check)原理:check 函数签名、成功/失败条件、阈值(threshold)关联
在容量压测中,仅依赖 HTTP 状态码判断业务成功远远不够。k6 的 Check 机制允许测试人员自定义断言,将业务逻辑的正确性纳入压测度量体系。本章深入剖析 check 的函数签名、成功/失败判定逻辑,以及如何通过阈值(threshold)将检查结果与压测通过标准绑定。
4.1 check 函数签名与核心参数
check 是 k6 内置的全局函数,其完整签名如下:
check(val, sets, [tags])
| 参数 | 类型 | 说明 |
|---|---|---|
| val | any | 被检查的对象,通常是 HTTP 响应对象(res)或 JSON 解析后的数据 |
| sets | object | 键值对集合:键为检查名称(字符串),值为断言函数(返回 boolean) |
| tags(可选) | object | 附加标签,用于在结果中区分不同维度的检查 |
典型调用示例:
import http from 'k6/http';
import { check } from 'k6';
export default function () {
let res = http.get('https://test-api.example.com/orders');
check(res, {
'状态码为 200': (r) => r.status === 200,
'响应时间 < 500ms': (r) => r.timings.duration < 500,
'订单列表非空': (r) => JSON.parse(r.body).length > 0,
});
}
最佳实践:每个检查名称应使用可读性强的中文或英文短语,便于在报告中快速定位失败项。避免使用模糊名称如 "check1"、"test2"。
4.2 成功/失败条件判定机制
check 的判定逻辑遵循以下规则:
- 成功:断言函数返回
true,该次检查记为 pass(通过)。 - 失败:断言函数返回
false或抛出异常,该次检查记为 fail(失败)。 - 异常处理:若断言函数内部发生错误(如访问未定义属性),k6 自动捕获异常并视为失败,不会中断 VU 执行。
常见断言模式对比:
| 断言类型 | 示例 | 适用场景 |
|---|---|---|
| 精确匹配 | (r) => r.status === 201 |
验证创建操作返回指定状态码 |
| 范围判断 | (r) => r.timings.duration < 1000 |
验证响应时间在性能基线内 |
| JSON 字段校验 | (r) => JSON.parse(r.body).code === 0 |
验证业务返回码 |
| 正则匹配 | (r) => r.body.includes('success') |
验证响应正文包含特定关键词 |
注意:不要在 check 内部执行耗时操作(如二次 HTTP 请求、大文件解析),这会拖慢 VU 执行速度,影响压测真实性。复杂校验应放在 check 外部预处理。
4.3 阈值(threshold)关联:将检查结果转化为通过标准
阈值是 k6 中定义压测通过/失败边界的关键机制。通过 thresholds 配置,可以将 check 的通过率与压测结果绑定。
阈值语法:
export let options = {
thresholds: {
'checks': ['rate>0.95'], // 所有检查综合通过率 > 95%
'http_req_duration': ['p(95)<2000'], // 95% 请求响应时间 < 2s
'checks{type:critical}': ['rate==1.0'], // 带标签的检查必须 100% 通过
},
};
阈值表达式说明:
| 指标 | 阈值表达式 | 含义 |
|---|---|---|
checks |
rate>0.99 |
所有 check 的通过率必须大于 99% |
checks{name:"状态码为 200"} |
rate==1.0 |
特定名称的检查必须 100% 通过 |
checks{group:critical} |
rate>0.999 |
带 group=critical 标签的检查通过率 > 99.9% |
容量压测水位口径边界测试中的阈值策略:建议将核心业务检查(如支付成功、下单成功)的阈值设为
rate==1.0,非核心检查(如推荐位加载)设为 rate>0.95。当系统接近容量水位时,核心检查的失败是触发边界告警的关键信号。
4.4 check 与阈值关联的完整流程图
4.5 带标签的检查与多维阈值
当压测场景包含多个业务接口时,使用标签(tags)可以将检查按维度分组,实现精细化阈值控制。
import http from 'k6/http';
import { check } from 'k6';
export default function () {
let res1 = http.get('https://api.example.com/orders');
check(res1, {
'订单接口状态码正确': (r) => r.status === 200,
}, { type: 'critical', service: 'order' });
let res2 = http.get('https://api.example.com/recommend');
check(res2, {
'推荐接口响应正常': (r) => r.status === 200,
}, { type: 'non-critical', service: 'recommend' });
}
export let options = {
thresholds: {
'checks{type:critical}': ['rate==1.0'], // 核心接口必须 100% 通过
'checks{type:non-critical}': ['rate>0.90'], // 非核心接口允许 10% 失败
'checks{service:order}': ['rate>0.99'], // 订单服务整体通过率 > 99%
},
};
标签命名规范:建议使用
type(业务等级)、service(服务名)、env(环境)等通用键名,便于在 k6 结果仪表盘和 Grafana 中统一筛选。
4.6 检查点与容量水位边界的关系
在容量压测中,检查点的失败率是判断系统是否达到容量水位的核心指标之一。以下表格总结了不同水位下的检查点表现:
| 水位阶段 | 检查点通过率 | 典型表现 | 阈值告警 |
|---|---|---|---|
| 正常水位 | 100% | 所有断言通过,响应时间稳定 | 无告警 |
| 高水位 | 99% ~ 100% | 偶发超时,非核心检查偶尔失败 | 非核心阈值触发 |
| 临界水位 | 95% ~ 99% | 核心检查开始出现失败,响应时间明显上升 | 核心阈值触发 |
| 过载水位 | < 95% | 大量请求失败,系统进入熔断或降级 | 严重告警,压测终止 |
边界测试口径:在容量压测中,通常将 核心检查通过率首次低于 99.9% 的时刻定义为“容量水位边界”。此时系统尚未完全崩溃,但已出现可观测的业务质量劣化,是进行容量规划和限流配置的关键参考点。