一、为什么要在k6告警时自动保留现场
你在做性能测试的时候,肯定遇到过这种情况:用k6压测接口,刚跑了几分钟就收到告警说请求成功率低,可到底是当时服务器卡了?还是接口本身有问题?还是你写的压测脚本有漏洞?这些疑问没有明确的现场数据支撑,排查起来要翻日志、查系统指标,花半天甚至一天都搞不定。自动保留现场的核心,就是在k6触发告警的瞬间,把当时的所有关键数据打包存档,不用手动找,节省大量排查时间。
1.1 核心思路拆解
简单来说就是三个步骤:k6跑测试时把自定义指标推到Prometheus;Prometheus设告警规则,符合阈值就触发通知;收到告警后自动拉取k6日志、系统指标这些现场数据,打包存好。整个流程不用人工干预,触发告警就自动干活,完美解决“告警后没数据查”的痛点。
二、用到的基础工具(通俗版)
先给大家说清楚每个工具是干啥的,不用记复杂概念,知道怎么用就行:
2.1 k6是什么
就是一个简单好用的性能测试工具,写几行JS脚本就能模拟大量用户请求,还能自己统计接口的成功率、响应时间这些自定义指标,是现在很多公司性能测试的首选工具,入门门槛很低。
2.2 Prometheus是什么
一个专门存系统和业务指标的工具,比如你服务器的CPU、内存、每个接口的响应时间,都能存在这里,还能设置告警规则,只要指标满足条件(比如成功率低于95%)就发通知,相当于整个监控体系的“大脑”。
2.3 联动的关键
k6的自定义指标要先推到Prometheus里,再让Prometheus根据指标设告警,告警触发后调用自动存现场数据的脚本,把两边的数据(k6的测试数据+Prometheus的系统数据)整合起来,就是完整的现场信息。
三、具体实现步骤+完整示例
这里所有示例都用本地环境演示,不用复杂的集群,跟着步骤走就能跑起来:
3.1 第一步:写k6脚本,自定义关键指标
技术栈:k6 + Prometheus Pushgateway + JavaScript Pushgateway是个中转站,k6把指标推给它,Prometheus定期从它那取数据,本地测试非常方便。
import http from 'k6/http';
import { trend, rate } from 'k6/metrics';
import { check } from 'k6';
// 1. 自定义两个关键指标:接口响应时间(用来慢接口排查)、请求成功率(用来触发告警)
const apiRespTime = new trend('api_response_time');
const successRate = new rate('api_success_rate');
export const options = {
// k6的运行配置:虚拟用户数10,测试时长30秒
vus: 10,
duration: '30s',
// 把自定义指标推到Pushgateway,每5秒推一次,Prometheus才能拿到最新数据
ext: {
"prometheus": {
"url": "http://localhost:9091", // Pushgateway的默认端口,本地要先启动
"pushInterval": "5s"
}
},
// 阈值设置:成功率低于95%时,k6会标记测试失败,也会同步给Prometheus
thresholds: {
'api_success_rate': ['rate>0.95']
}
};
// 压测的核心逻辑,每个用户都会执行这个函数
export default function () {
// 替换成你要压测的接口地址
const res = http.get('http://test.api.com/users');
// 把当前请求的响应时间加到自定义指标里,方便后续分析
apiRespTime.add(res.timings.duration);
// 检查请求是否成功(状态码200算成功),成功就给成功率指标加1
const isSuccess = check(res, { '请求成功': (r) => r.status === 200 });
successRate.add(isSuccess);
}
3.2 第二步:配置Prometheus告警规则
技术栈:Prometheus YAML 这里写一个简单的告警规则,只要连续10秒请求成功率低于95%就触发告警,避免临时波动误报。
# 告警规则组名称,随便起
groups:
- name: k6-alerts
rules:
# 告警规则:k6请求成功率过低
- alert: K6_SuccessRate_Low
# 计算10秒内的平均成功率,公式:成功请求数 / 总请求数
expr: rate(api_success_rate_sum[10s]) / rate(api_success_rate_count[10s]) < 0.95
# 满足条件持续10秒才触发,防止误报
for: 10s
# 告警的级别,这里设为严重
labels:
severity: critical
# 告警的描述信息,会在通知里显示
annotations:
summary: "k6压测请求成功率异常"
description: "当前k6测试成功率为 {{ $value }},低于95%阈值,请立即排查"
3.3 第三步:写告警联动的脚本,自动保存现场
技术栈:Shell + jq 这里用Alertmanager接收Prometheus的告警,然后触发这个Shell脚本,自动把现场数据打包存好。脚本逻辑是:解析告警信息、复制k6的测试日志、拉取触发时段的系统指标、最后压缩成压缩包。
#!/bin/bash
# 这个脚本是Alertmanager的webhook接收端,要跑在本地的8080端口
# 接收Alertmanager发来的JSON告警数据
ALERT_INFO=$(cat)
# 用jq工具解析JSON里的关键信息,jq是处理JSON的小工具,要提前安装
ALERT_NAME=$(echo "$ALERT_INFO" | jq -r '.alerts[0].labels.alertname')
TRIGGER_TIME=$(echo "$ALERT_INFO" | jq -r '.alerts[0].startsAt' | sed 's/[:TZ-]//g')
# 1. 创建临时存档目录,用告警名称和时间命名,避免重复
SAVE_DIR="./k6_alert_${ALERT_NAME}_${TRIGGER_TIME}"
mkdir -p "$SAVE_DIR"
# 2. 复制k6的测试数据,提前把k6的日志和结果存到本地,比如这里假设日志叫k6_test.log,结果叫k6_results.json
cp ./k6_test.log "$SAVE_DIR/"
cp ./k6_results.json "$SAVE_DIR/"
# 3. 从Prometheus拉取告警触发前后的系统指标(CPU、内存),方便排查当时的服务器状态
PROM_URL="http://localhost:9090/api/v1/query_range"
# 把时间转成Unix时间戳,Prometheus的API需要这个格式
START_TIME=$(date -d "$TRIGGER_TIME" -d "5 minutes ago" +%s)
END_TIME=$(date -d "$TRIGGER_TIME" -d "5 minutes later" +%s)
# 拉取CPU使用率指标
CPU_QUERY="avg(irate(node_cpu_seconds_total{mode!='idle'}[1m]))"
curl -s "${PROM_URL}?query=${CPU_QUERY}&start=${START_TIME}&end=${END_TIME}&step=15s" > "${SAVE_DIR}/prometheus_cpu.json"
# 拉取内存使用率指标
MEM_QUERY="1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)"
curl -s "${PROM_URL}?query=${MEM_QUERY}&start=${START_TIME}&end=${END_TIME}&step=15s" > "${SAVE_DIR}/prometheus_mem.json"
# 4. 打包压缩包,方便下载和查看
tar -zcvf "${SAVE_DIR}.tar.gz" "$SAVE_DIR"
# 删除临时目录,节省空间
rm -rf "$SAVE_DIR"
echo "现场数据已保存:${SAVE_DIR}.tar.gz"
四、方案的优缺点和注意事项
4.1 优点
- 完全自动:触发告警不用人工操作,直接保存现场数据,节省排查时间至少80%
- 数据全面:既有k6的测试细节(哪个接口慢、哪些请求失败),又有服务器的系统状态(当时是不是CPU满了),能快速定位问题根源
- 灵活定制:想存什么数据、存到哪里,都可以改脚本,适合不同公司的需求
4.2 缺点
- 组件多:需要装k6、Prometheus、Pushgateway、Alertmanager、jq这些工具,本地测试要花10分钟搭环境
- 小开销:告警触发时拉取Prometheus数据会占用一点网络和计算资源,对测试环境没影响
4.3 注意事项
- 权限问题:Pushgateway、Prometheus的端口要开放,脚本要有读写权限,不然存不了数据
- 阈值合理:成功率阈值设95%比较合适,太严格会频繁告警,太宽松起不到作用
- 定期清理:旧的现场压缩包要定期删,不然占磁盘空间,建议保留最近1周的
- 日志路径:要提前把k6的日志和结果存到脚本能找到的地方,不然复制失败
五、应用场景
这个方案适合所有需要做性能测试和问题排查的场景:
- 日常迭代的性能回归测试:每次提交代码都跑k6压测,触发告警自动存现场,避免上线后出问题
- 线上接口的日常监控:用k6模拟线上真实流量压测,触发异常自动留存数据,快速定位线上接口故障
- 新人问题排查:新人遇到性能问题,不用翻大量文档和日志,直接拿压缩好的现场数据,10分钟就能了解当时的情况
六、总结
这个方案的核心就是把k6的自定义测试指标和Prometheus的告警体系结合,让告警触发后自动保存完整的现场数据,从根本上解决了性能测试排查时“找不到数据”的痛点。整个流程通俗易懂,代码示例完整,即使是刚接触性能测试的开发者也能跟着跑起来,大大提升性能测试和问题排查的效率。
评论
围绕“k6阈值警报触发后如何自动保留现场,结合自定义指标与Prometheus告警联动机制”参与讨论