设计一个 Prometheus 记录规则,把 95 线 RT 每 5 分钟滚动计算一次

解读

  1. 95 线 RT 即 P95 响应时间,需用 Prometheus 的 histogram_quantile 函数从 Histogram 型指标中抽取。
  2. “每 5 分钟滚动计算一次” 指:
    • 计算窗口为 5 min,用 5m 区间向量;
    • 记录规则 evaluation_interval 通常设为 30 s 或 1 min,保证 5 min 窗口持续滑动,而不是只算一次。
  3. 国内生产环境普遍使用 kube-prometheus 或 VictoriaMetrics 集群版,规则文件统一放在 PrometheusRule CRD 中,由 operator 热加载,命名需符合《阿里研发规约》或《华为云监控命名规范》:小写+下划线,带维度后缀。
  4. 必须考虑指标基数爆炸:只保留必要维度(如 service、method、status_class),丢弃高基数字段(如 pod、instance、trace_id)。
  5. 规则需加注释说明用途与负责人,方便 SRE 二次审核,这是国内大厂面试的“隐形得分点”。

知识点

  • Histogram 与 Summary 区别:Histogram 可聚合,Summary 不可;生产环境只允许 Histogram。
  • histogram_quantile(φ, sum(rate(...[5m])) by (le, ...)) 是固定范式,φ=0.95。
  • 记录规则语法:groups.name、interval、record、expr、labels。
  • 滑动窗口与 evaluation_interval 关系:窗口≥evaluation_interval,否则会出现“空窗”。
  • 国内常用高基数维度过滤技巧:
    – 预聚合时去掉 instance、pod;
    – 只保留 status_class(2xx/4xx/5xx)而非 status_code;
    – 对 method 做映射,如把 /user/123 映射成 /user/{id}。
  • 规则上线流程:本地检查 promtool check rules → Git PR → 自动 CI 验证 → ArgoCD 同步 → 灰度集群观察 30 min → 全量发布。

答案

在业务 Namespace 下新建 PrometheusRule 资源,文件:p95-rt-5m.yaml

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: svc-p95-rt-5m
  namespace: monitoring
  labels:
    prometheus: k8s
    role: alert-rules
spec:
  groups:
  - name: performance.p95_rt_5m
    interval: 30s
    rules:
    - record: svc:http_request_duration_p95_5m
      expr: |
        histogram_quantile(0.95,
          sum(
            rate(http_request_duration_seconds_bucket{
              __name__=~"http_request_duration_seconds_bucket",
              status_class!~"5.."
            }[5m])
          ) by (le, service, method, status_class, cluster)
        )
      labels:
        unit: seconds
        team: perf
        comment: "滚动 5min P95 响应时间,已过滤 5xx,维度已降基"

关键点说明

  1. 选用 http_request_duration_seconds_bucket,符合国内 SpringBoot、Go-Micro 默认埋点规范。
  2. 用 status_class!~"5.." 剔除 5xx,避免错误流量放大 P95;如业务需要一起观测可删除该过滤。
  3. by (le, service, method, status_class, cluster) 保留四大低基维度,instance、pod 已去掉,可让指标量级从百万级降到千级。
  4. interval: 30s 保证 5 min 窗口持续滑动;如需更低延迟可改为 15s,但需确保 Prometheus 端存储压力可控。
  5. 记录规则命名以 svc: 开头,符合“指标命名三段式”规范,方便 Grafana 模板自动联想。

上线验证

promtool check rules p95-rt-5m.yaml
kubectl apply -f p95-rt-5m.yaml

观察 Prometheus UI → Rules 页面,确认 svc:http_request_duration_p95_5m 持续有新数据;再跑

curl -G http://prometheus:9090/api/v1/query --data-urlencode 'query=svc:http_request_duration_p95_5m{service="order"}'

返回非空即表示规则生效。

拓展思考

  1. 业务突发脉冲时,5 min 窗口可能“抹平”尖峰,如何兼顾灵敏度与稳定性?
    可再建一条 1 min 窗口的 P95 记录规则,命名为 svc:http_request_duration_p95_1m,用于实时告警;而 5 min 规则继续用作容量报告与 SLA 统计。
  2. 若 Histogram Bucket 边界不合理,导致 P95 落在 +Inf,如何快速定位?
    在 Grafana 添加辅助面板:histogram_quantile(1.0, ...) 与最大 bucket 边界对比,若两者相等,说明需要调大 bucket 上限或增加更细粒度 bucket。
  3. 国内金融级场景要求“多活机房”维度,如何在记录规则里兼容?
    在 by 子句加入 zone 或 idc 维度,但需提前做桶预聚合,防止跨机房拉取造成查询放大;也可在 Thanos Receive 层做全局降采样后再计算 P95。
  4. 规则上线后想回滚,最安全的做法是什么?
    在 PrometheusRule 里加 annotation: rollback_rev: abc123,与 Git commit id 绑定;回滚时直接 revert PR,由 ArgoCD 自动回退,30s 内即可生效,无需重启 Prometheus。