4. k6 指标与输出:内置指标、自定义指标与输出方式

在容量压测中,指标(Metrics)是衡量系统性能的核心数据。k6 提供了丰富的内置指标,并允许通过自定义扩展创建专属指标。本章将深入解析 k6 的指标体系与输出机制,帮助你精准捕获压测数据。

k6 指标体系架构图 k6 指标体系架构 k6 指标来源 内置指标(Built-in) 自定义指标(Custom) http_req_duration http_req_failed vus / vus_max iterations / data_* Trend Counter Gauge Rate 输出方式:终端 / JSON / 云端 内置指标自动采集,自定义指标通过 k6/metrics 包手动创建与上报

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 云端结果聚合与可视化
k6 指标输出流程 k6 指标输出流程 k6 脚本执行 指标采集引擎 输出处理器 终端(stdout) JSON 文件 CSV 文件 InfluxDB Prometheus 支持同时输出到多个目标:k6 run --out json=result.json --out influxdb=http://localhost:8086/k6 script.js

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 等,灵活适配不同分析场景。
  • 标签系统让指标具备多维聚合能力,是深入分析性能瓶颈的关键。
  • 阈值机制将指标与通过条件绑定,实现自动化质量门禁。