
楠风测开 · 测试工程师复习日记 Day14Prometheus Grafana采集与告警配置故障验收AI 异常检测前言朋友们好我是楠风。Day 11—13我们复习了 Linux 命令、AI 辅助写 Shell以及性能瓶颈排查。今天接着把Linux 监控告警 AI 智能监控串起来。先想一个场景订单接口持续返回 500CPU 却只有 20%告警群里也没有消息。究竟是业务指标没有采集、规则没有命中还是通知没有送到这篇围绕已有测试环境给出采集配置、看板查询、告警规则和验收方法再说明异常检测模型怎样接入。数字和场景均用于教学不代表线上实测效果。一、基础篇先确认组件分工和环境前提本文假设你已经有可访问的 Prometheus、Grafana、Alertmanager以及运行 node_exporter 的 Linux 测试主机。接口部分还需要应用提供请求计数和耗时指标。各组件的安装、网络和权限应先准备好。组件本文中的职责node_exporter暴露 Linux CPU、内存等主机指标应用埋点或网关暴露请求量、状态码、耗时等接口指标Prometheus定时抓取、保存时间序列、评估告警规则Grafana查询 Prometheus用看板对照指标变化Alertmanager接收告警、分组和去重并发往接收渠道Linux 主机 / 应用 → 暴露指标 → Prometheus ├─ Grafana 查询 → 看板 └─ 规则评估 → Alertmanager → 通知本文选择 Prometheus 负责规则评估。Grafana 是旁路展示告警不需要先经过 Grafana。node_exporter 也不会替应用生成订单接口指标。组件架构说明完整监控还要覆盖处理动作消息应该说明哪个服务、什么异常、持续多久以及先检查什么。日志和调用链则帮助定位原因按时间、服务名、请求 ID 与指标对应即可不必为了一个练习同时搭建所有日志组件。二、实战篇先让 Prometheus 采到指标2.1 配置采集目标和 Alertmanager 地址下面是prometheus.yml的相关配置。已有同名顶层项时合并内容不要重复添加scrape_configs等键。示例中的linux-test、order-app、alertmanager都是待替换的地址需要能从 Prometheus 所在环境访问。路径同样以 Prometheus 进程或容器内部为准。global: scrape_interval: 15s evaluation_interval: 15s rule_files: - /etc/prometheus/alerts.yml alerting: alertmanagers: - static_configs: - targets: [alertmanager:9093] scrape_configs: - job_name: node static_configs: - targets: [linux-test:9100] - job_name: order-demo metrics_path: /metrics static_configs: - targets: [order-app:8080]应用要实际提供/metrics。如果使用其他端点例如部分框架的/actuator/prometheus应按实际地址修改改路径不会自动启用埋点。将配置交给现有部署加载并确认规则文件已挂载或保存在对应路径。配置加载方式按你的部署管理方式执行。Prometheus 配置文档2.2 先查抓取状态再查具体指标在 Prometheus 查询up{jobnode}值为1表示对应目标最近一次抓取成功0表示抓取失败。没有结果时先检查任务名、标签和目标是否存在。接着检查是否有node_cpu_seconds_total等主机指标。也可以从 Prometheus 所在网络访问采集端的/metrics检查端点是否真的暴露指标。node_exporter 接入示例抓取成功只说明能拿到指标不能证明业务正常。接口请求失败时应用的指标端点仍然可能正常响应。三、看板篇用同一时间范围观察主机和接口在 Grafana 添加 Prometheus 数据源填写 Grafana 服务端可访问的地址然后验证连接。容器中的localhost指该容器自身不能照搬浏览器访问地址。Grafana 数据源文档先做两个主机面板确认实例筛选一致。CPU 非空闲时间占比单位%100 * ( 1 - avg by (instance) ( rate(node_cpu_seconds_total{jobnode, modeidle}[5m]) ) )内存已用比例单位%100 * ( 1 - node_memory_MemAvailable_bytes{jobnode} / node_memory_MemTotal_bytes{jobnode} )CPU 表达式反映非空闲时间比例还需结合 I/O 等指标解释原因内存计算使用可用内存不能简单把缓存占用理解为内存故障。接口看板则先覆盖请求速率、错误率和延迟。下面假设应用提供 Counterhttp_requests_total标签包含service、route、method、status创建订单为POST /orders。请求速率单位请求/秒sum by (service) ( rate(http_requests_total{ joborder-demo, route/orders, methodPOST }[5m]) )5xx 错误比例取值为01sum by (service) ( rate(http_requests_total{ joborder-demo, route/orders, methodPOST, status~5.. }[5m]) ) / sum by (service) ( rate(http_requests_total{ joborder-demo, route/orders, methodPOST }[5m]) )分子、分母统计同一接口和窗口先对各条 Counter 使用rate再聚合。Grafana 可选用接收01的百分比单位避免已经乘了 100 又按比例显示。若应用另外提供传统 Histogramhttp_request_duration_seconds_bucket可增加 P95 延迟面板单位为秒histogram_quantile( 0.95, sum by (service, le) ( rate(http_request_duration_seconds_bucket{ joborder-demo, route/orders, methodPOST }[5m]) ) )这里保留le才能对传统直方图桶计算分位数。实际指标名、标签和桶边界需要与埋点对应P95 也是基于桶的估计值。查询函数说明已知状态的计数序列应初始化为零并持续暴露。没有 5xx 序列、没有请求、采集失败是不同状态不应统一显示成“错误率 0”。指标初始化建议四、告警篇从一条能验收的规则开始4.1 用采集失败规则验证通知链路将下面内容保存到前面配置指定的alerts.ymlgroups: - name: linux-monitoring rules: - alert: TargetScrapeFailed expr: up{jobnode} 0 for: 1m labels: severity: warning annotations: summary: Linux 主机指标抓取失败 description: 目标 {{ $labels.instance }} 抓取失败持续 1 分钟确认规则被加载后在测试环境暂停 node_exporter观察up变为0规则进入pending条件持续成立后进入firing。恢复采集再检查规则是否解除。for: 1m表示条件持续成立 1 分钟并不是故障发生 1 分钟后消息必达。采集、规则评估和通知分组都有自己的时间设置。告警状态说明4.2 配置接收器核对消息格式下面是 Alertmanager 使用通用 webhook 的配置示意地址必须换成你已部署、能接收 Alertmanager 消息格式的接收服务。它不是可直接使用的群机器人地址。route: receiver: test-webhook group_by: [alertname, instance] group_wait: 10s group_interval: 1m repeat_interval: 4h receivers: - name: test-webhook webhook_configs: - url: http://notification-adapter:8080/alerts send_resolved: true如果发到企业微信、钉钉等渠道应选择支持该渠道的接收器或适配服务。不能假设不同 webhook 的请求体格式一致。还要核对路由、静默、分组等待以及接收端实际响应。Alertmanager 接收器配置Prometheus 显示触发、Alertmanager 收到告警、群里收到消息要分别记录。设置了send_resolved后也要实际验证恢复通知。4.3 CPU 正常不应阻止接口错误告警不要把“CPU 超过 80%”作为“接口错误率高”的必要条件。配置错误、依赖异常等情况可能让请求很快失败而 CPU 不高。接口规则可以独立描述为同一服务的POST /orders最近 5 分钟 5xx 比例超过 5%平均请求速率至少每秒 1 次条件持续 1 分钟。下面这条规则追加到同一规则组的rules列表中与TargetScrapeFailed同级- alert: OrderApiHigh5xxRate expr: | ( sum by (service) ( rate(http_requests_total{ joborder-demo, route/orders, methodPOST, status~5.. }[5m]) ) / sum by (service) ( rate(http_requests_total{ joborder-demo, route/orders, methodPOST }[5m]) ) 0.05 ) and on (service) ( sum by (service) ( rate(http_requests_total{ joborder-demo, route/orders, methodPOST }[5m]) ) 1 ) for: 1m labels: severity: warning annotations: summary: 订单接口 5xx 错误率持续超过 5%先在查询页面分别验证比例和流量两部分再组合成规则。否则一条很长的表达式没有结果时难以区分是指标缺失、标签不匹配还是条件没有达到。流量门槛能减少低请求量下的比例波动但也会漏掉低频故障关键接口需要额外的主动探测或业务失败规则。这里也只统计 HTTP 5xx接口返回 200 但订单创建失败需要单独定义业务成功与失败指标。所有阈值都应结合测试服务的正常流量和故障目标确定。单纯把阈值调高可能只是让通知变少并没有改善监控效果。调整前后应使用相同故障场景验证确保减少的是不需要处理的通知。五、验收篇正常、故障、恢复都要测场景操作与检查重点正常基线保持采集和成功请求确认指标更新、看板有数据、错误规则未触发采集失败暂停测试采集端检查up、等待状态、触发状态和通知送达接口故障通过测试应用已有的故障开关或依赖桩制造持续 5xx确认 CPU 正常时仍能发现故障恢复撤掉故障持续成功请求观察窗口错误率回落和恢复通知低流量或零请求检查规则覆盖缺口不把没有输出直接当成业务健康目标移除验证目标缺失规则up 0不覆盖所有目标消失情况接口故障测试需要应用提供受控注入方式本文没有附带订单服务代码。执行时记录“开始故障、条件成立、规则触发、消息到达、业务恢复、告警解除”的实际时间不用预期值替代实测。每轮测试尽量只改一个条件。例如先维持相同请求速率改变 5xx 占比确认规则行为后再改变流量观察门槛影响。若同时改了负载、错误比例和采集配置很难判断告警变化由哪个因素造成。验收记录还应保留规则版本、测试时间范围和关键查询结果。故障恢复后检查接收人是否能从消息找到对应看板或排查说明。能够发出消息只是链路的一部分消息能否支持处理也值得放进验收标准。目标被移除后相关序列可能不再存在因此还需根据预期目标清单设计缺失检测。服务整体无数据可用absent_over_time等函数辅助判断多实例场景还要防止剩余实例掩盖某个实例缺失。缺失检测函数六、AI 赋能篇在已有监控上增加异常检测6.1 先分清统计基线与模型假设接口平时 P95 约 100ms最近变成 250ms却还没碰到 500ms 阈值。这是否异常需要对照流量、时段和历史分布。均值加标准差、同一时段对比等方法可以构成动态基线。3σ是统计判别思路让 AI 写出脚本不会自动把它变成机器学习模型。分布偏斜、周期高峰和训练窗口混入故障都会影响判定。需要联合多个指标时可以试验 Isolation Forest。每分钟生成一行特征包含请求速率、5xx 比例、P95 延迟和 CPU 非空闲比例训练与预测使用相同服务范围、单位和列顺序。6.2 一个有明确输入约定的核心函数以下代码需要已安装numpy、scikit-learn。输入是预先整理好的二维数值数组四列依次为rps、error_ratio、p95_seconds、cpu_ratio训练集使用经复核的历史正常时段待检测集使用后续时段。import numpy as np from sklearn.ensemble import IsolationForest def detect_windows(normal_history, new_samples): train np.asarray(normal_history, dtypefloat) test np.asarray(new_samples, dtypefloat) for name, values in [(train, train), (test, test)]: if values.ndim ! 2 or values.shape[1] ! 4: raise ValueError(f{name} 必须是四列二维数组) if len(values) 0 or not np.isfinite(values).all(): raise ValueError(f{name} 不能为空也不能包含缺失或无穷值) model IsolationForest(random_state42, contaminationauto) model.fit(train) return model.predict(test), model.decision_function(test)predict返回-1表示模型判为异常1表示判为正常decision_function越小越异常。contaminationauto使用算法默认阈值不代表自动学会了你的业务故障标准。Isolation Forest 文档这个函数只覆盖核心训练与预测。还需要实现指标查询、时间对齐、缺失处理、模型保存和定时评分。不同主机和服务不能随意拼接应用跑在多台主机时先定义 CPU 等资源特征怎样与服务对应。6.3 检测任务也要纳入监控接入路径可以这样安排Prometheus 指标 → 按时间窗口整理特征 → 检测任务评分 → 暴露异常结果、最后成功时间等指标 → Prometheus 抓取并评估规则 → Alertmanager 通知初期先观察和人工复核。按时间划分训练集与验证集加入正常高峰、发布变更、故障演练和恢复样例分别记录误报、漏报、发现延迟。阈值调整后用后续独立时段再检查。复核时以业务故障时段为参照区分“一个故障产生多个异常窗口”和“发现多个不同故障”。同时记录正常时段的告警次数避免只展示成功识别的样例。模型是否有帮助要看它补上了哪些原规则未覆盖的问题以及额外增加了多少处理工作。缺失数据不要直接补成零否则采集故障可能被包装成业务低谷。检测任务自身停止、评分结果过期也需要告警。模型输出异常不等于已经定位根因明确的业务故障规则仍应保留。可以把下面的要求交给 AI 补充测试清单输入是每分钟的请求速率、5xx比例、P95延迟和CPU比例。 请检查时间对齐、特征单位、正常高峰、低流量、采集缺失、 故障恢复和检测任务停止等情况。 分别写出输入、预期行为和需要人工确认的条件。 不要编造准确率不要把模型异常直接解释为故障根因。七、排错篇遇到现象先检查哪里现象优先检查up没有结果job 名、目标是否加载、标签筛选、目标是否被移除up1接口面板没数据应用是否埋点指标名和标签是否与查询一致Grafana 一直显示无数据数据源连通性、时间范围、变量筛选、数据单位比例正常但图上显示异常是否混用01与0100分子分母范围是否一致规则触发群里没消息Alertmanager 地址、路由、静默、接收器和消息格式服务恢复告警还在滑动窗口是否仍包含失败请求规则与分组时间是否满足模型突然大量报异常输入单位或列顺序变化、缺失数据、流量规律和版本变更写在最后今天的小练习是选一台测试主机和一个测试服务确认指标、做出看板、验证通知然后走完正常、故障与恢复。当这条链路能够解释清楚再让模型帮助发现固定阈值之外的变化。每增加一种检测能力都配上可以执行的验收场景。下期预告Day 15 · MySQL 基础 AI SQL 优化从常用 SQL、查询结果验证和性能分析开始看看怎样让 AI 辅助改写查询再核对结果与执行计划。 楠风测开 · 测试工程师复习日记