标签与分组
负载测试通常针对具有不同子系统和资源的服务。这使得很难准确找出导致性能下降的问题。
为了帮助您可视化、排序和过滤测试结果,k6 会将以下内容添加到您的结果中。
- 标签 用于对您的检查、阈值、自定义指标和请求进行分类,以便进行深入过滤。
- 分组 用于将标签应用于脚本的函数。
除了这些细粒度的标签外,您还可以使用选项设置测试范围的标签。您可以使用这些标签来比较多次测试的结果。
除了过滤结果外,您还可以使用标签来限制阈值分析的操作。
标签
标签是一种强大的方式,用于分类您的 k6 实体并过滤测试结果。
k6 提供两种类型的标签
- 系统标签。 k6 自动分配的标签。
- 用户自定义标签。 您在编写脚本时添加的标签。
系统标签
目前,k6 默认自动创建以下标签
标签 | 描述 |
---|---|
proto | 使用的协议名称(例如 HTTP/1.1 ) |
subproto | 子协议名称(由 websockets 使用) |
status | HTTP 状态码(例如 200 、404 等) |
method | HTTP 方法名称(例如 GET 、POST 等)或 gRPC 的 RPC 方法名称 |
url | HTTP 请求 URL |
name | HTTP 请求名称 |
group | 完整的分组路径,详情请参见前述解释 |
check | 检查名称 |
error | 非 HTTP 错误消息字符串(例如网络或 DNS 错误) |
error_code | 指定错误类型的数字;当前错误码列表可在错误码页面找到 |
tls_version | TLS 版本 |
scenario | 发出指标的场景名称 |
service | gRPC 的 RPC 服务名称 |
expected_response | 基于 responseCallback 的 true 或 false ;默认检查状态是否为 2xx 或 3xx |
要禁用上述某些标签,请使用 systemTags
选项。请注意,某些数据收集器(例如 cloud
运行)可能需要特定的标签。
以下系统标签是可选的。请根据需要启用它们
标签 | 描述 |
---|---|
vu | 执行请求的虚拟用户 ID |
iter | 迭代次数 |
ip | 远程服务器的 IP 地址 |
ocsp_status | 在线证书状态协议 (OCSP) HTTPS 状态 |
用户自定义标签
定义您自己的标签,根据您的测试逻辑对 k6 实体进行分类。您可以为以下实体添加标签
- 请求
- 检查
- 阈值
- 自定义指标
import http from 'k6/http';
import { Trend } from 'k6/metrics';
import { check } from 'k6';
const myTrend = new Trend('my_trend');
export default function () {
// Add tag to request metric data
const res = http.get('https://quickpizza.grafana.com/', {
tags: {
my_tag: "I'm a tag",
},
});
// Add tag to check
check(res, { 'status is 200': (r) => r.status === 200 }, { my_tag: "I'm a tag" });
// Add tag to custom metric
myTrend.add(res.timings.connecting, { my_tag: "I'm a tag" });
}
测试范围的标签
除了将标签附加到请求、检查和自定义指标外,您还可以为所有指标设置测试范围的标签。您可以通过两种方式设置这些标签
在 CLI 中,使用一个或多个
--tag NAME=VALUE
标志在脚本本身中
export const options = { tags: { name: 'value', }, };
代码定义的标签
在这种情况下,如果需要使用高级逻辑处理要设置的用户自定义标签,则可以通过代码定义标签来实现。
为了支持高级标签工作流程,也可以直接从脚本代码中设置和获取它们。
k6/execution.vu.tags 对象的属性确实可以直接赋值新的键/值对来动态定义新标签。正如以下示例所示,这对于从嵌套分组中跟踪容器的分组以及聚合嵌套分组的子指标非常有用。
import http from 'k6/http';
import exec from 'k6/execution';
import { group } from 'k6';
export const options = {
thresholds: {
'http_reqs{container_group:main}': ['count==3'],
'http_req_duration{container_group:main}': ['max<1000'],
},
};
export default function () {
exec.vu.tags.containerGroup = 'main';
group('main', function () {
http.get('https://test.k6.io');
group('sub', function () {
http.get('https://quickpizza.grafana.com/');
});
http.get('https://quickpizza.grafana.com/api/headers');
});
delete exec.vu.tags.containerGroup;
http.get('https://quickpizza.grafana.com/api/delay/3');
}
使用相同的 API,您还可以检索任何已设置的用户自定义或系统定义的标签
import exec from 'k6/execution';
export default function () {
const tag = exec.vu.tags['scenario'];
console.log(tag); // default
}
标签阶段
借助 k6-jslib-utils 项目中的一些辅助函数,如果执行器支持 stages
选项,您可以添加带有当前正在进行阶段的标签。与其他标签类似,该标签会添加到迭代期间收集的所有样本中。
为执行的操作添加标签的一种方法是调用 tagWithCurrentStageIndex
函数,设置一个 stage
标签来标识执行它们的阶段
import http from 'k6/http';
import exec from 'k6/execution';
import { tagWithCurrentStageIndex } from 'https://jslib.k6.io/k6-utils/1.3.0/index.js';
export const options = {
stages: [
{ target: 5, duration: '2s' },
{ target: 10, duration: '5s' },
],
};
export default function () {
tagWithCurrentStageIndex();
// all the requests will have a `stage` tag
// with its value equal to the index of the stage
http.get('https://test.k6.io'); // e.g. {stage: "1"}
}
此外,一个性能画像函数 tagWithCurrentStageProfile
可以添加一个带有当前运行阶段计算出的性能画像的标签
import http from 'k6/http';
import exec from 'k6/execution';
import { tagWithCurrentStageProfile } from 'https://jslib.k6.io/k6-utils/1.3.0/index.js';
export const options = {
stages: [{ target: 2, duration: '5s' }],
};
export default function () {
tagWithCurrentStageProfile();
// all the requests are tagged with a `stage` tag
// with the index of the stage as value
http.get('https://test.k6.io'); // {stage_profile: ramp-up}
}
基于当前阶段的性能画像值可以是以下选项之一
性能画像 | 描述 |
---|---|
ramp-up | 当前阶段的目标高于前一阶段的目标 |
steady | 当前阶段的目标等于前一阶段的目标 |
ramp-down | 当前阶段的目标低于前一阶段的目标 |
结果输出中的标签
{
"type ": "Point ",
"data ": {
"time ": "2017-05-09T14:34:45.239531499+02:00 ",
"value ": 459.865729,
"tags ": {
"group ": "::my group::json ",
"method ": "GET ",
"status ": "200 ",
"url ": "http://quickpizza.grafana.com"
}
},
"metric ": "http_req_duration "
}
{
"type ": "Point ",
"data ": {
"time ": "2017-05-09T14:34:45.625742514+02:00 ",
"value ": 5,
"tags ": null
},
"metric ": "vus "
}
要查看标签如何影响您的测试结果输出,请参阅k6 结果输出语法。
分组
为了更好地组织,可以使用 分组 按函数组织负载脚本。您还可以嵌套分组以进行 BDD 风格的测试。
在 分组 中发出的所有指标都带有标签 group
,其值为所有包裹分组的名称,名称之间用 ::
(两个冒号)分隔。根分组使用名称 ''(空字符串)。如果您的单个分组名为 cool requests
,则 group
的实际值为 ::cool requests
。
例如,您可以使用分组按页面加载或用户操作来组织多个请求。
import { group } from 'k6';
export default function () {
group('visit product listing page', function () {
// ...
});
group('add several products to the shopping cart', function () {
// ...
});
group('visit login page', function () {
// ...
});
group('authenticate', function () {
// ...
});
group('checkout process', function () {
// ...
});
}
分组在内部执行以下任务
对于每个
group()
函数,k6 会发出一个 group_duration 指标,其中包含执行分组函数的总时间。当可标记资源(检查、请求或自定义指标)在分组内运行时,k6 会将标签
group
设置为当前分组名称。更多信息请参阅标签部分。
group_duration
指标和 group tagging
这两个选项都可以帮助您分析和可视化复杂的测试结果。请查看它们在您的k6 结果输出中的工作方式。
不推荐: 每个请求一个分组
将每个请求包裹在一个分组内可能会增加不必要的样板代码。
import { group, check } from 'k6';
import http from 'k6/http';
const id = 5;
export default function () {
// reconsider this type of code
group('get post', function () {
http.get(`http://example.com/posts/${id}`);
});
group('list posts', function () {
const res = http.get(`http://example.com/posts`);
check(res, {
'is status 200': (r) => r.status === 200,
});
});
}
如果您的代码类似于前面的代码片段,请考虑以下策略来编写更简洁的代码
- 对于动态 URL,请使用URL 分组功能。
- 要为您的请求提供有意义的名称,请设置 tags.name 的值。
- 要重用通用逻辑或更好地组织代码,可以将逻辑分组到函数中,或者创建本地 JavaScript 模块并将其导入到测试脚本中。
- 要建模高级用户模式,请查看场景。