4. k6 指标与输出:内置指标、自定义指标与输出方式
在容量压测中,指标(Metrics)是衡量系统性能的核心数据。k6 提供了丰富的内置指标,并允许通过自定义扩展创建专属指标。本章将深入解析 k6 的指标体系与输出机制,帮助你精准捕获压测数据。
4.1 内置指标详解
k6 在每次 HTTP 请求、VU 生命周期和迭代过程中自动收集一系列内置指标。这些指标无需额外声明,开箱即用。
| 指标名称 | 类型 | 说明 | 典型用途 |
|---|---|---|---|
http_req_duration |
Trend | HTTP 请求总耗时(包含 DNS、连接、TLS、发送、等待、接收) | 核心延迟指标,P95/P99 监控 |
http_req_failed |
Rate | HTTP 请求失败率(基于 status >= 400 或自定义条件) | 错误率告警 |
http_req_sending |
Trend | 发送请求数据耗时 | 网络上传性能分析 |
http_req_waiting |
Trend | 等待服务器响应耗时(TTFB) | 服务端处理能力评估 |
http_req_receiving |
Trend | 接收响应数据耗时 | 网络下载性能分析 |
vus |
Gauge | 当前活跃虚拟用户数 | 并发量监控 |
vus_max |
Gauge | 最大虚拟用户数配置 | 资源上限验证 |
iterations |
Counter | 累计迭代执行次数 | 吞吐量统计 |
data_sent / data_received |
Counter | 发送/接收的字节数 | 网络流量统计 |
💡 提示:
http_req_duration 是压测中最关键的指标。k6 默认将其拆分为 http_req_sending、http_req_waiting、http_req_receiving 三个子阶段,便于定位瓶颈。
4.2 自定义指标:四种类型
当内置指标无法满足业务需求时,k6 提供 k6/metrics 包,允许在 JavaScript 脚本中创建自定义指标。四种指标类型各有适用场景:
| 类型 | 构造函数 | 数据特性 | 适用场景 | 输出示例 |
|---|---|---|---|---|
| Trend | new Trend(name) |
记录数值分布(最小、最大、平均、百分位) | 响应时间、处理耗时、延迟分布 | avg=120.5, min=45, max=890, p(95)=350 |
| Counter | new Counter(name) |
单调递增计数 | 请求总数、错误次数、业务量统计 | count=15234 |
| Gauge | new Gauge(name) |
记录当前瞬时值(取最后一次上报值) | 连接池大小、队列深度、内存使用率 | value=42 |
| Rate | new Rate(name) |
记录布尔值比率(true 的比例) | 成功率、通过率、可用性 | rate=0.9876 |
4.2.1 自定义指标代码示例
import http from 'k6/http';
import { Trend, Counter, Gauge, Rate } from 'k6/metrics';
// 声明自定义指标
const myTrend = new Trend('api_response_time');
const myCounter = new Counter('api_call_count');
const myGauge = new Gauge('active_connections');
const myRate = new Rate('api_success_rate');
export default function () {
const resp = http.get('https://test-api.example.com/users');
// Trend:记录响应时间
myTrend.add(resp.timings.duration);
// Counter:每次调用递增
myCounter.add(1);
// Gauge:记录当前连接数(假设从响应头获取)
myGauge.add(parseInt(resp.headers['X-Active-Connections'] || '0'));
// Rate:记录请求是否成功
myRate.add(resp.status === 200);
}
⚠️ 注意:自定义指标的名称必须全局唯一,不能与内置指标重名。建议使用业务前缀,如
order_create_duration、payment_success_rate。
4.3 指标输出方式
k6 支持多种输出方式,方便在压测过程中实时查看和事后分析。
4.3.1 终端输出(默认)
运行 k6 run script.js 时,终端会实时显示指标摘要。默认输出包含:
- 实时进度条:显示当前 VU 数、迭代次数、持续时间
- 内置指标汇总:
http_req_duration的 avg、min、med、max、p(90)、p(95) - 自定义指标:按类型显示对应统计值
data_received..................: 12 MB 240 kB/s
data_sent......................: 2.1 MB 42 kB/s
http_req_duration.............: avg=145.2ms min=32.1ms med=120.5ms max=890.3ms p(90)=280.4ms p(95)=350.1ms
http_req_failed...............: 1.24% ✓ 152 ✗ 12100
api_response_time.............: avg=145.2ms min=32.1ms med=120.5ms max=890.3ms p(90)=280.4ms p(95)=350.1ms
api_call_count................: 12252 245.0/s
active_connections............: 42
api_success_rate..............: 98.76% ✓ 12100 ✗ 152
4.3.2 JSON 输出
使用 --out json 参数将指标输出为 JSON 文件,便于后续导入分析工具或自定义处理。
k6 run --out json=results.json script.js
JSON 输出格式示例:
{"type":"Point","metric":"http_req_duration","data":{"time":"2025-01-15T10:30:00Z","value":145.2,"tags":{"url":"https://test-api.example.com/users","status":"200"}}}
{"type":"Point","metric":"api_response_time","data":{"time":"2025-01-15T10:30:00Z","value":145.2,"tags":{}}}
{"type":"Point","metric":"api_call_count","data":{"time":"2025-01-15T10:30:00Z","value":1,"tags":{}}}
{"type":"Point","metric":"api_success_rate","data":{"time":"2025-01-15T10:30:00Z","value":true,"tags":{}}}
📌 关键点:JSON 输出每行一个指标点,包含时间戳、指标名、值和标签。适合用
jq、pandas 或 Grafana 进行后处理。
4.3.3 其他输出方式
| 输出方式 | 命令参数 | 适用场景 |
|---|---|---|
| CSV | --out csv=results.csv |
Excel 或表格工具分析 |
| InfluxDB | --out influxdb=http://localhost:8086/k6 |
实时时序数据库存储 |
| Prometheus | --out prometheus |
Prometheus 生态集成 |
| k6 Cloud | --out cloud |
云端结果聚合与可视化 |
4.4 指标标签(Tags)与分组
标签是 k6 指标系统的核心扩展能力。通过为指标添加标签,可以在输出时按维度聚合分析。
import http from 'k6/http';
import { Trend } from 'k6/metrics';
const orderDuration = new Trend('order_create_duration');
export default function () {
// 为不同 API 端点添加标签
const endpoints = ['/api/order/create', '/api/order/update', '/api/order/delete'];
endpoints.forEach((endpoint) => {
const resp = http.get(`https://api.example.com${endpoint}`);
// 添加标签:endpoint 和 status
orderDuration.add(resp.timings.duration, {
endpoint: endpoint,
status: resp.status.toString(),
});
});
}
输出时,标签会作为 JSON 字段或终端分组显示:
order_create_duration..............: avg=120.5ms
✓ { endpoint:/api/order/create, status:200 }...: avg=95.2ms
✓ { endpoint:/api/order/update, status:200 }...: avg=145.8ms
✓ { endpoint:/api/order/delete, status:200 }...: avg=110.3ms
💡 最佳实践:为自定义指标添加
endpoint、status、method、region 等业务标签,便于在 Grafana 或 InfluxDB 中做多维下钻分析。
4.5 阈值(Thresholds)与指标联动
阈值允许基于指标值定义通过/失败条件,是自动化压测的关键环节。
export const options = {
thresholds: {
// 内置指标阈值
http_req_duration: ['p(95)<500', 'p(99)<1000'],
http_req_failed: ['rate<0.05'],
// 自定义指标阈值
api_response_time: ['avg<200', 'max<1000'],
api_success_rate: ['rate>0.99'],
},
};
当阈值未达标时,k6 会在终端输出 ✗ 标记,并以非零退出码结束进程,便于 CI/CD 集成。
4.6 本章小结
- 内置指标覆盖 HTTP 请求、VU 状态、迭代和流量等基础维度,开箱即用。
- 自定义指标提供 Trend、Counter、Gauge、Rate 四种类型,满足业务级监控需求。
- 输出方式支持终端、JSON、CSV、InfluxDB、Prometheus 等,灵活适配不同分析场景。
- 标签系统让指标具备多维聚合能力,是深入分析性能瓶颈的关键。
- 阈值机制将指标与通过条件绑定,实现自动化质量门禁。