Administrator
Administrator
发布于 2026-11-03 / 0 阅读
0
0

Prometheus 从入门到生产实践(12):Grafana 与 SLO:正确展示、错误预算和多窗口燃尽

本篇是《Prometheus 从入门到生产实践》第 12 / 24 篇。配置以文中版本与环境前提为准,实验和故障均为教学场景。完整程序、配置及校验范围见配套实验包。

从正确的业务查询到图表单位,再到 SLI、错误预算与燃尽告警

把指标画出来只是第一步。一个可用的大盘应该让人知道当前有多少流量、失败了多少、延迟如何、数据是否可信;SLO 则进一步回答这些结果是否满足用户体验目标。本篇把展示和可靠性判断连接起来。

1. 先确认 Grafana 从哪里连接 Prometheus

共享实验的 Prometheus 位于本机 19090,demo 位于 19100。如果 Grafana 也在同一主机网络环境,可以将数据源指向 http://127.0.0.1:19090。

如果 Grafana 运行在容器里,127.0.0.1 指 Grafana 容器自身,不能因为浏览器能打开 Prometheus 就假定数据源也能连。应使用 Grafana 服务端所在环境可达的地址,例如同一容器网络中的 Prometheus 服务名与其容器监听端口。

保存数据源后先做连接检查,再在 Explore 运行 up{job="demo"}。排障时把数据源连接问题和 PromQL 空结果分开。

2. 做四块能解释业务的大盘

面板 查询思路 单位与注意点
请求速率 sum(rate(ops_demo_requests_total{job="demo"}[5m])) requests/s,不是累计次数
5xx 比例 同范围错误速率除以总速率 0~1 比例,Grafana 选对应百分比单位
P95 延迟 第 9 篇的聚合 bucket 查询 输入单位为秒,面板也按秒处理
抓取状态 up{job="demo"} 区分 0、1 与无数据

给每块面板写上窗口、聚合范围和无数据语义。不要让 panel 标题写“每秒请求”,表达式却使用原始 counter。

秒与毫秒也要只转换一次。输入是 0.2 秒,可以让单位自动显示为 200ms;如果表达式已经乘了 1000,就应把面板单位设置为毫秒,而不是再按秒格式化。

3. 查询步长、窗口和变量不能靠界面猜

Grafana 的范围查询会选择 step,rate 的窗口是另一项设置。数据源的抓取间隔与面板 min step 等配置应对应实际情况,而不是任意填一个很小数字让曲线“更细”。

Grafana 提供 $__rate_interval 宏辅助选择 rate 窗口。下面属于 Grafana 编辑器语法,宏需要先由 Grafana 展开,不能原样交给 Prometheus API:

sum by (route) (
  rate(ops_demo_requests_total{job=~"${job:regex}"}[$__rate_interval])
)

job 变量可从指标的 job 标签取值;多选时使用明确的正则格式化。重复面板、多选变量和“全部”范围会放大查询数量,面板越多越需要关注资源开销。查询编辑器机制见 Grafana Prometheus 文档。

4. SLI、SLO 与错误预算是什么关系

SLI 是测量服务表现的指标;SLO 是在指定窗口内希望达到的目标。这里选择“符合范围的请求中,非 5xx 请求比例”为可用性 SLI,目标为滚动 30 天达到 99.9%。这只是教学定义,真实业务可能还需要计入超时、网关错误和取消请求。

允许的坏请求比例是 1 - 0.999 = 0.001,即 0.1%。这是按请求数定义的预算,不能直接等同为任意情况下固定多少分钟停机;请求流量并不总是均匀。

若应用停止,客户端根本没把请求计入 counter,单靠应用内部错误率可能看起来很好。因此 SLI 的测量位置和覆盖范围要与用户体验对应,采集链路和外部探测也需要单独监控。

5. 燃尽率把异常转换成预算消耗速度

燃尽率可以写成“当前坏请求比例 / 允许坏请求比例”。当当前错误率为 1%,而允许值为 0.1%,燃尽率就是 10 倍。

快的长窗口与短窗口同时超标,可以减少对陈旧故障或瞬时尖峰的误判。例如滚动 30 天的教学设计:

类别 长窗口与短窗口 燃尽率阈值 预算含义近似
快速消耗 1h 与 5m 14.4 倍 该速度持续一小时约消耗 2% 的 30 天预算
持续消耗 6h 与 30m 6 倍 该速度持续六小时约消耗 5% 的预算

这些是用于说明原理的设计起点,不是所有系统通用的阈值。窗口、流量、值班响应时间和业务容忍度都应参与决策。方法背景见 Google SRE 的 SLO 告警实践。

6. 规则如何落地

配套 a-slo.rules.yml 包含四个错误率窗口和两条燃尽告警,属于可选扩展,需要明确加入 rule_files 并按流程检查、重载才会生效。为避免与第 11 篇记录名称冲突,使用单独的 ops_demo_slo_bad 记录名。这份规则假设固定的 200、500 counter 已初始化输出;不满足时先应用第 10 篇的明确基线策略,不能把缺失直接当健康。

groups:
  - name: demo-slo-availability
    interval: 1m
    rules:
      - record: job_route:ops_demo_slo_bad:ratio5m
        expr: |
          sum by (job, route) (rate(ops_demo_requests_total{job="demo",code=~"5.."}[5m]))
          /
          sum by (job, route) (rate(ops_demo_requests_total{job="demo"}[5m]))
      - record: job_route:ops_demo_slo_bad:ratio1h
        expr: |
          sum by (job, route) (rate(ops_demo_requests_total{job="demo",code=~"5.."}[1h]))
          /
          sum by (job, route) (rate(ops_demo_requests_total{job="demo"}[1h]))
      - record: job_route:ops_demo_slo_bad:ratio30m
        expr: |
          sum by (job, route) (rate(ops_demo_requests_total{job="demo",code=~"5.."}[30m]))
          /
          sum by (job, route) (rate(ops_demo_requests_total{job="demo"}[30m]))
      - record: job_route:ops_demo_slo_bad:ratio6h
        expr: |
          sum by (job, route) (rate(ops_demo_requests_total{job="demo",code=~"5.."}[6h]))
          /
          sum by (job, route) (rate(ops_demo_requests_total{job="demo"}[6h]))
      - alert: DemoSLOBurnFast
        expr: |
          (job_route:ops_demo_slo_bad:ratio1h > 14.4 * 0.001)
          and on (job, route)
          (job_route:ops_demo_slo_bad:ratio5m > 14.4 * 0.001)
          and on (job, route)
          (sum by (job, route) (rate(ops_demo_requests_total{job="demo"}[5m])) > 0)
        for: 2m
        labels:
          severity: critical
          slo: availability-99_9
        annotations:
          summary: '错误预算快速消耗:{{ $labels.job }} {{ $labels.route }}'
          description: '1h 与 5m 窗口同时超过 14.4 倍预算燃尽率,请核对请求错误、数据完整性和用户影响。'
      - alert: DemoSLOBurnSlow
        expr: |
          (job_route:ops_demo_slo_bad:ratio6h > 6 * 0.001)
          and on (job, route)
          (job_route:ops_demo_slo_bad:ratio30m > 6 * 0.001)
          and on (job, route)
          (sum by (job, route) (rate(ops_demo_requests_total{job="demo"}[30m])) > 0)
        for: 15m
        labels:
          severity: warning
          slo: availability-99_9
        annotations:
          summary: '错误预算持续消耗:{{ $labels.job }} {{ $labels.route }}'
          description: '6h 与 30m 窗口同时超过 6 倍预算燃尽率,请安排调查并核对通知路由。'

长短窗口用 and on(job,route) 对齐同一个业务范围。额外的有流量条件防止把未定义比例当作有效错误率,但“只要有一个请求”未必适合低流量系统。是否增加最小请求量,或改用事件计数与外部探测,要按业务定义。

for 的具体状态和通知链路会在后续章节展开。这里的 critical、warning 只是标签,只有 Alertmanager 路由或值班平台消费它们后,才会改变实际通知行为。

7. 规则测试和数据覆盖分别验证

a-slo.test.yml 用八小时的合成输入分别测试持续 6% 失败与健康流量,预期前者在选定检查时刻有两条 firing 告警,后者没有。运行方式:

promtool check rules a-slo.rules.yml
promtool test rules a-slo.test.yml

这些命令需要在具备 promtool 的环境实际执行并记录结果;教学文件本身不证明测试已经通过。合成输入验证数学和状态,不能证明生产采集完整。

刚启动十分钟,[6h] 仍可能基于现有样本返回值;这不表示它已经覆盖完整六小时。30 天合规报告同样需要相应的保留期、稳定的测量位置和缺失数据处理,不能只把查询窗口改长就宣布达标。

8. 验收与练习

先用共享实验产生正常、错误和慢请求,核对四块基础面板;再用合成数据验证 SLO 规则,而不是在真实服务上制造故障去等六小时。

最后给这份大盘写一段使用说明:SLI 统计什么、不统计什么,单位是否转换,数据源从哪连接,空数据如何解释,告警发给谁。广度来自把展示、采集和通知串起来;深度来自每个数字都能追溯到清晰的定义。


上一篇:查询性能与记录规则:从定位开销到合成测试 · 系列目录 · 下一篇:告警规则进阶:持续时间、稳定标签、缺失数据与单元测试


评论