先确认 MCP 到 Prometheus 的连接、scrape target 和样本完整性,再用 PromQL 按服务、实例、Pod、版本缩小异常范围,最后用处置前后的同口径指标复核。MCP 会话已经建立或工具有返回值,只能说明 MCP 层有响应,不代表 Prometheus 已经采集到数据,更不代表故障已经恢复。
本文沿用掘金热榜《AIOps(一):基于 Prometheus MCP + WorkBuddy 构建 AI 智能运维》中的 AIOps 场景,但不会把热榜文章当成 MCP 工具接口文档。服务地址、认证方式、工具名、参数和写操作能力,必须以实际使用的 Prometheus MCP 项目及其版本对应的官方 README 为准。
先查数据链路,别把“没数据”交给 AI 猜
整条链路如下:
WorkBuddy(发起查询、整理证据)→ Prometheus MCP(工具适配)→ Prometheus(查询与规则)→ 返回结果 → 生成处置建议 → 再次查询验证
这条链路里,MCP 是查询入口,不是数据来源。真正需要回答的是:WorkBuddy 调用的是哪个 Prometheus、查询时间窗口是什么、目标有没有被抓到、返回的序列是否覆盖了故障时段。
在接入前,先记录一份“能力契约”。这至少要明确 MCP 服务地址、认证与超时配置、PromQL 工具的实际名称和参数、返回的时序或告警字段格式,以及是否提供重启、扩缩容、回滚等写操作。由于不同 MCP 项目的工具名和参数差异很大,不应凭经验写一个启动命令或配置片段。部署时应固定镜像 tag,以该 tag 的 README 为准,同时保留 WorkBuddy 实际发出的请求和 MCP 日志,方便区分客户端问题与下游问题。
排查时按连接层、适配层和采集层依次推进。第一步确认 WorkBuddy 能发现 MCP 服务,并完成一次最小只读调用。若服务不可达,要区分地址解析、连接建立、MCP 握手和工具执行这几个阶段;认证失败时,也要区分是访问 MCP 的凭据失效,还是 MCP 访问 Prometheus 时认证失败。超时可能是 MCP 到 Prometheus 的连接超时,也可能是 PromQL 执行时间过长,而参数错误通常能在工具 schema 或 MCP 日志里看到具体不匹配项。
第二步检查 MCP 服务日志,确认请求是否到达、PromQL 是否被完整传递、下游查询是否结束。同一条 PromQL 如果在 Prometheus 原生查询入口可以执行,经过 MCP 却失败,重点比较两者是否指向同一 Prometheus 或同一租户、表达式和时间范围是否一致,以及 MCP 是否对返回结果做了类型转换、截断或额外过滤。此时应查看原始 MCP 请求,不要只看 WorkBuddy 对结果的文字总结。
第三步再检查采集链路。原生入口能够执行 PromQL,但结果为空或目标持续 DOWN,说明问题通常不在 MCP。相关 Docker MCP 网关排障资料建议先检查 scrape_targets 状态,并验证 Prometheus 指标端点的可达性。若 MCP 网关与 Prometheus 同处一个 Linux 容器,可执行:
curl -fsS http://localhost:9090/metrics
如果 Prometheus 位于其他容器或主机,localhost 就不再代表 Prometheus,必须换成实际服务地址。这个命令验证的是 Prometheus 自身端点,不等同于某个 exporter 的 /metrics 是否可访问。被抓取目标的连通性应从 Prometheus 所在网络环境核对,并用下面的查询观察目标状态:
up{job="<job>"}
在采用 up 指标的抓取配置中,1 表示最近一次抓取成功,0 表示失败。目标持续为 DOWN 时,再检查服务发现是否生成了目标、DNS 和网络是否可达,以及目标端点、认证或 TLS 配置是否发生变化。目标未生成与目标已生成但抓取失败,是两个不同的问题。
采集正常,也不代表数据足以支持判断。资料列出的典型数据质量问题包括采集延迟大、缺失值多和毛刺较多:前两类要从采集与聚合侧排查,毛刺则可能直接干扰异常判断和告警阈值。因此,“查到了数据”之后还要确认覆盖范围、连续性和新鲜度,不能只看查询是否报错。
PromQL 的“空结果”至少要区分三种情况。第一种是表达式无法解析,例如函数参数、范围向量或标签匹配器写错;第二种是表达式合法,但没有匹配到任何序列,通常与指标名、标签值、目标或时间窗口有关;第三种是存在序列,但不满足过滤条件。IBM Cloud Monitoring 的文档说明,PromQL 告警查询只返回满足指定条件的时间序列,因此“有序列但告警没触发”不能归入无数据。
可以先用下面这条查询确认某个 job 下实际出现了哪些指标名:
count by (__name__) (
{job="<job>"}
)
这里仍然要求 <job> 与目标真实暴露的标签一致。不要让 WorkBuddy 根据业务名称猜指标名,先从目标元数据、已有查询或指标清单中取得准确名称,再替换占位符。
排查中常用的一组 PromQL 模板如下。它们适用于支持这些 PromQL 函数的 Prometheus 版本;5m、指标名和标签都必须按实际采集间隔、指标类型及标签结构调整:
up{job="<job>"}
sum by (service) (
rate(<counter_total>{service="<service>"}[5m])
)
topk(10,
sum by (instance) (
rate(<counter_total>{service="<service>"}[5m])
)
)
histogram_quantile(
0.95,
sum by (le) (
rate(<duration_seconds_bucket>{service="<service>"}[5m])
)
)
第一组模板用于确认抓取状态,第二组按服务聚合请求量或错误量,第三组找出贡献最大的实例,第四组估算延迟分位数。<counter_total> 必须是 counter,不能把普通 gauge 直接套进 rate();范围窗口内也需要有足够样本。上述 histogram_quantile() 查询针对 classic histogram;如果使用 native histogram,表达式要根据目标 Prometheus 版本另行核对。多个服务共用同一组 bucket 时,可以增加 service 分组,但前提是该标签真实存在。
错误率最好同时看错误量和请求量:
100 *
sum by (service) (
rate(<error_counter_total>{service="<service>"}[5m])
)
/
sum by (service) (
rate(<request_counter_total>{service="<service>"}[5m])
)
如果请求量为零,除法结果可能是空值或 NaN,这时应单独查看分母,不能把“没有算出错误率”解释成“没有错误”。
告警界面缺少 PromQL 选项,需要单独排查。Nightingale 的 Docker 部署中确实存在看不到 PromQL 创建选项的现象;同一份资料也说明,业务组的多级继承在底层告警执行中仍是扁平机制,现有摘录并没有给出选项缺失的确定根因。因此不要把调整业务组层级直接当成解决方案,更不要照搬其他版本的菜单路径。
比较稳妥的核验方式是记录实际镜像 tag、前后端版本和创建规则时的日志,再与该版本官方文档和发布说明对照;可以比较同版本、相同部署方式的正常环境,但不要在没有证据时把账号权限、浏览器缓存或某个开关直接写成根因。升级也应先确认发布说明、兼容性和回滚方式。
用 PromQL 把告警缩到服务、实例和变更
告警出现后,先把自然语言描述转成可复现的查询契约。至少固定异常开始和结束时间、受影响环境与服务、观察到的症状和预期症状、已经排除的范围,以及最近发生的发布、扩缩容和配置变更。时间尽量使用明确的绝对起止值,并记录时区,避免 WorkBuddy、MCP 和 Prometheus 分别按相对时间计算出不同窗口。
接下来的查询顺序应当稳定。先用 up 类查询确认目标是否仍被抓取,再分别查看即时值和范围趋势,然后检查请求量、错误量、延迟和资源饱和度,最后才按实例、Pod、版本、区域及依赖关系下钻。即时值适合回答“现在是什么状态”,范围查询更适合发现短时尖峰、采集断点和恢复后的再次异常,二者不能互相替代。
MCP 调用还应固定查询起止时间和返回粒度。否则同一个“最近五分钟”在不同工具里可能对应不同范围,或者一次拿 instant query、另一次拿 range query,最后很难比较。范围向量 [5m] 也是查询窗口,不等于目标一定在最近五分钟内成功采集;窗口内样本不足时,rate() 仍可能无法计算。
定位时先用聚合确认异常集中在哪里,再用排序找出主要贡献者。sum by (service) 用来比较服务,topk(10, sum by (instance) (...)) 用来找实例,但按绝对错误量排序容易把高流量实例排在前面,低流量但错误率极高的实例反而被遗漏。因此还要按实例比较错误率、请求量和自身基线。
版本和区域下钻同样遵循这个原则。service、instance、pod、node、version、region 都不是 Prometheus 自动保证存在的标签,只能使用目标实际暴露的值。例如:
sum by (version) (
rate(<counter_total>{service="<service>"}[5m])
)
如果某个版本流量结构不同,只比较绝对请求量仍可能得出错误结论,需要把错误率、饱和度和请求量放在一起看。聚合还会丢失维度:sum by (service) 的结果里本来就不会保留 instance 或 pod,所以“聚合后看不到实例”通常不是数据消失,而是查询口径本来就没有保留这些标签。
静态阈值造成的噪声,也不一定是 Prometheus 查询出了问题。异常检测用于从时间序列中发现异常波动,为告警、自动止损和根因分析提供依据。资料所讨论时期的开源 Prometheus 主要依赖阈值规则进行检测,困难包括海量指标难以配置统一阈值、业务变化导致旧阈值持续误报,以及规则维护成本不断上升。
动态基线更适合具有稳定历史、周期性明显且指标语义没有变化的序列,例如随时间段规律变化的流量。稀疏的二元事件、刚发布的新指标、持续采集缺口,以及违反明确 SLO 的硬故障,并不适合仅靠历史波动判断。WorkBuddy 可以负责选择基线、运行对比查询和整理证据,但它不是异常检测算法本身,更不能仅凭几条同步变化的曲线证明根因。
为了避免模型把相关性写成结论,可以要求 WorkBuddy 固定输出以下结构:
结论: "异常目前集中在哪个服务或实例"
时间窗口: "明确的起止时间和时区"
支持证据:
- "实际执行的 PromQL"
- "关键返回值和时间范围"
已排除: "已经通过查询排除的范围"
待验证假设: "仍缺少证据的推断"
下一条查询: "用于验证假设的具体表达式"
置信度: "低、中或高"
置信度依据: "为什么可以给出这个判断"
缺失证据: "标签、样本、日志或依赖关系中的缺口"
置信度不应只是一个没有依据的百分比。若缺少某个维度的标签、目标处于 DOWN 状态或时间窗口不完整,就应明确降级结论。
常见失败可按固定分支排查。查询为空时,先核对准确指标名、标签值和时间窗口,再确认目标是否被持续抓取;不要立即缩短范围或换指标碰运气。错误量下降但请求量也同步下降时,不能判断为错误率恢复。多个服务在相近时间同时异常时,应先查共同依赖和同一批变更,再比较各自的发布时间线。即使时间完全吻合,也只能说明相关性,仍需要日志、发布记录、依赖指标或受控实验补足因果证据。
处置后用同口径指标复核,才算闭环
只有采集目标恢复、症状指标改善,并在可比时间窗口内保持稳定,才能把事件标记为已恢复。进程存在、服务端口监听或日志里出现“启动成功”,都不足以作为恢复证据。
处置前先明确四件事:哪条证据支持当前判断,准备执行什么动作,预计影响哪些服务或实例,以及什么指标持续多久才算恢复。执行前还需要明确审批人、权限范围和回滚方案。对重启、扩容、回滚或流量切换这类动作,应分别定义成功条件。例如,重启要确认新实例重新成为可抓取目标;扩容要确认新实例已接流量且整体饱和度没有恶化;回滚则要同时检查版本标签和业务症状是否回到处置前水平。
MCP 写操作只有在实际服务提供相应能力、权限可控并经过人工确认时才能执行。没有写接口时,WorkBuddy 应输出可复制的运行手册,而不是把“建议重启”写成“已经重启”。具备写接口也不意味着可以自动扩大操作范围,命令目标、资源范围和回滚动作都应受到限制;能幂等执行的操作还应尽量设计为幂等。
处置后复用处置前的 PromQL,保持指标名、标签匹配、范围窗口、聚合方式、时间粒度和比较时长一致,仅切换查询对应的处置前后时间点。验证至少覆盖以下几层:
| 验证层 | 复用查询 | 通过条件 |
|---|---|---|
| 采集链路 | up{job="<job>"} 及样本连续性 |
目标恢复抓取,数据重新出现且没有明显陈旧窗口 |
| 核心症状 | 错误量、错误率或原始异常指标 | 回到告警规则或 SLO 定义的范围内 |
| 延迟与饱和度 | 延迟分位数、队列长度、CPU、内存等实际指标 | 尖峰消退,容量压力没有转移到别处 |
| 业务结果 | 请求量、订单量、任务完成量等业务指标 | 没有因错误下降而出现业务量消失 |
| 告警状态 | 原告警及关联告警 | 告警解除,并在后续观察窗口内没有立即复发 |
通过条件应来自已有 SLO、告警阈值或运行手册,不能临时让模型编一个“看起来正常”的数值。对于业务流量存在周期性的服务,观察窗口还应覆盖与故障相关的业务阶段,而不是刚重启几秒就宣布恢复。
以下情况都不能算恢复:进程已启动但 target 仍为 DOWN;单个查询点恢复,范围查询随后再次异常;错误指标回落但请求量或业务量同时消失;采集仍然延迟,看到的只是旧值;只处理了一个实例,其他异常实例没有变化。尤其是“错误数从 100 降到 0,同时请求数从 1000 降到 0”,这通常不是修复成功。
验证失败时,应按预先定义的路径执行回滚或止损动作,保留处置前后的查询结果和时间点,再从新的时间原点重新定位。不要在同一份失真的证据上反复重启,也不要仅凭 WorkBuddy 的总结关闭工单。重新验证仍然失败时,应升级人工介入,并记录哪些假设已经被排除。
审计记录至少要保留告警或工单编号、使用的 PromQL、查询时间窗口、关键返回值、采取的动作、执行人及审批记录、执行输出、验证查询和最终状态。涉及 MCP 写操作时,还要保留工具返回结果,但不能把返回的“success”字段直接当作业务恢复证明。
这套方法仍有明确边界。静态阈值会随业务变化失真,动态基线也不能弥补遥测缺失;没有日志、指标或变更记录时,模型无法可靠定位故障。指标同步变化只能提供相关性,不能自动证明因果关系。MCP 的工具名称、参数、认证和权限还会随项目版本变化,自动处置也必须保留人工审批、最小权限和可回滚边界。真正完成的 AIOps 闭环,不是“AI 给出了一个根因”,而是每一步都有可复现查询、可核对证据和明确的恢复标准。












暂无评论内容