设计一个 Prometheus 记录规则,把 95 线 RT 每 5 分钟滚动计算一次
解读
- 95 线 RT 即 P95 响应时间,需用 Prometheus 的 histogram_quantile 函数从 Histogram 型指标中抽取。
- “每 5 分钟滚动计算一次” 指:
- 计算窗口为 5 min,用 5m 区间向量;
- 记录规则 evaluation_interval 通常设为 30 s 或 1 min,保证 5 min 窗口持续滑动,而不是只算一次。
- 国内生产环境普遍使用 kube-prometheus 或 VictoriaMetrics 集群版,规则文件统一放在 PrometheusRule CRD 中,由 operator 热加载,命名需符合《阿里研发规约》或《华为云监控命名规范》:小写+下划线,带维度后缀。
- 必须考虑指标基数爆炸:只保留必要维度(如 service、method、status_class),丢弃高基数字段(如 pod、instance、trace_id)。
- 规则需加注释说明用途与负责人,方便 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,维度已降基"
关键点说明
- 选用 http_request_duration_seconds_bucket,符合国内 SpringBoot、Go-Micro 默认埋点规范。
- 用 status_class!~"5.." 剔除 5xx,避免错误流量放大 P95;如业务需要一起观测可删除该过滤。
- by (le, service, method, status_class, cluster) 保留四大低基维度,instance、pod 已去掉,可让指标量级从百万级降到千级。
- interval: 30s 保证 5 min 窗口持续滑动;如需更低延迟可改为 15s,但需确保 Prometheus 端存储压力可控。
- 记录规则命名以 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"}'
返回非空即表示规则生效。
拓展思考
- 业务突发脉冲时,5 min 窗口可能“抹平”尖峰,如何兼顾灵敏度与稳定性?
可再建一条 1 min 窗口的 P95 记录规则,命名为 svc:http_request_duration_p95_1m,用于实时告警;而 5 min 规则继续用作容量报告与 SLA 统计。 - 若 Histogram Bucket 边界不合理,导致 P95 落在 +Inf,如何快速定位?
在 Grafana 添加辅助面板:histogram_quantile(1.0, ...) 与最大 bucket 边界对比,若两者相等,说明需要调大 bucket 上限或增加更细粒度 bucket。 - 国内金融级场景要求“多活机房”维度,如何在记录规则里兼容?
在 by 子句加入 zone 或 idc 维度,但需提前做桶预聚合,防止跨机房拉取造成查询放大;也可在 Thanos Receive 层做全局降采样后再计算 P95。 - 规则上线后想回滚,最安全的做法是什么?
在 PrometheusRule 里加 annotation: rollback_rev: abc123,与 Git commit id 绑定;回滚时直接 revert PR,由 ArgoCD 自动回退,30s 内即可生效,无需重启 Prometheus。