土法炼钢兴趣小组的算法知识备份

【可观测性工程】真实事故复盘剧本:从指标抖动到根因的全链路追查

文章导航

分类入口
architectureobservability
标签入口
#incident-response#debugging#playbook#slo#prometheus#tempo#loki#profiling#ebpf#events

目录

真实事故复盘剧本:从指标抖动到根因的全链路追查

凌晨 02:14(本文时间均为 UTC+8 虚构)。PagerDuty 推送:CheckoutSLOBurnRateCritical1h firing,slo:checkout:burnrate1h > 14.4 已持续 2 分钟。Grafana SLO 面板:p99 从 120ms 升至 2.3s,错误率 0.05% → 3.2%。

本文是虚构但可复现的排障教材:实验环境、指标名、PromQL/LogQL、kubectl 命令均可在 minikube/docker-compose 演练栈复现。不发明工具行为——命令与面板路径对齐本系列 PrometheusSLO告警TracesLogsEvents内核追踪

事故排障时间线 排障信号链


一、演练环境与前置条件

1.1 拓扑(虚构 ecommerce 生产)

组件 版本假设 可观测性
checkout Go 1.22, 12 replicas OTel SDK → Collector
redis-cart Redis 7 redis_exporter
payment Java 17 OTel Java agent
inventory Go OTel
Prometheus 2.51 scrape + recording
Alertmanager 0.27 route → PagerDuty
Tempo 2.4 trace backend
Loki 3.0 {service="checkout"}
Grafana 11 SLO + RED dashboards

1.2 复现仓库结构(建议)

incident-lab/
  docker-compose.yml
  prometheus/rules/slo-checkout.yaml
  alertmanager/alertmanager.yml
  otel-collector/config.yaml
  apps/checkout/...

1.3 注入故障(与剧本一致)

# 模拟错误配置:将 redis maxclients 从 10000 改为 100 后滚动发布
kubectl patch configmap checkout-redis -n production --type merge -p '
{"data":{"redis.conf":"maxclients 100\ntimeout 300\n"}}'
kubectl rollout restart deployment/checkout-redis -n production
kubectl rollout restart deployment/checkout -n production

预期现象:连接池耗尽 → p99 上升 → Burn Rate Page。与主剧本一致。


二、Golden Minute(T+0 — T+5)

T+0:Ack 与确认

  1. PagerDuty Ack;打开 19-alerting runbook URL。
  2. Grafana → Dashboard slo-checkout → 确认非维护窗口静默。

T+1:RED 定性

信号 正常基线 事故值 推断
Rate 1.2k rps 1.15k rps 流量未跌
Errors 0.05% 3.2% 服务在失败
Duration p99 120ms 2.3s 尾部恶化

参考 指标体系 RED

T+2:变更审查

并行打开 Events 面板与:

kubectl:events

kubectl get events -n production --sort-by=.lastTimestamp | tail -20

输出片段记入 Incident 文档;与 Events 与变更关联 对照。

kubectl:rollout

kubectl rollout history deployment/checkout -n production

输出片段记入 Incident 文档;与 Events 与变更关联 对照。

kubectl:diff

kubectl diff -f deploy/checkout.yaml

输出片段记入 Incident 文档;与 Events 与变更关联 对照。

kubectl:configmap

kubectl get configmap checkout-redis -n production -o yaml

输出片段记入 Incident 文档;与 Events 与变更关联 对照。

kubectl:pods

kubectl get pods -n production -l app=checkout -o wide

输出片段记入 Incident 文档;与 Events 与变更关联 对照。

T+3:角色

角色 职责
Commander 决策回滚/熔断
Comms Slack #incidents 状态
Ops 执行 PromQL/LogQL

T+5:首次通报

[INC-2026-0618-0214] checkout p99 2.3s, err 3.2%. 疑 redis/连接池.
Investigating. ETA 30m update.

三、Metrics 阶段(T+5 — T+15)

3.1 两问定性

步骤 1:基线 p99

histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="checkout"}[5m])) by (le))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 2:按 instance

histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="checkout"}[5m])) by (le, instance))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 3:按 endpoint

histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="checkout",endpoint="/api/checkout/submit"}[5m])) by (le))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 4:错误率

sum(rate(http_requests_total{service="checkout",status=~"5.."}[5m])) / sum(rate(http_requests_total{service="checkout"}[5m]))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 5:Redis 客户端

histogram_quantile(0.99, sum(rate(redis_command_duration_seconds_bucket{service="checkout"}[5m])) by (le, command))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 6:连接池

redis_pool_connections_waiting{service="checkout"}

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 7:Burn Rate 1h

slo:checkout:burnrate1h

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 8:下游 payment

histogram_quantile(0.99, sum(rate(http_client_duration_seconds_bucket{service="checkout",peer="payment"}[5m])) by (le))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

3.2 与 SLO Recording Rules

确认 18-slo 规则已部署:

# prometheus/rules/slo-checkout.yaml(节选)
- record: slo:checkout:burnrate1h
  expr: |
    sum(rate(http_requests_total{service="checkout",status=~"5.."}[1h]))
    / sum(rate(http_requests_total{service="checkout"}[1h]))
    / (1 - 0.999)

四、Trace 阶段(T+15 — T+25)

4.1 从 Exemplar 跳转 Tempo

Grafana → checkout RED 面板 → 点击 p99 尖峰 exemplar → Trace ID 7f3a9c2e4b1d8f0a6e5c4b3a29180716(虚构固定值,实验可种子化)。

4.2 Span 分解(虚构 trace)

Span duration
checkout.submit 2300ms
redis_get_cart 850ms
payment.authorize 45ms
inventory.reserve 38ms

判断:Redis span 占比高 → 下游或连接池。

4.3 采样不足时

10-traces 临时调 tail sampling:

# otel-collector tail_sampling 片段
policies:
  - name: slow-checkout
    type: latency
    latency:
      threshold_ms: 200

等待 3–5 分钟再查 Tempo。


五、Log 阶段(T+20 — T+30)

LogQL:trace 关联

{service="checkout"} | json | trace_id="7f3a9c2e4b1d8f0a6e5c4b3a29180716"

关联 日志管道 的解析规则;确认 trace_id 字段在采集层注入。

LogQL:连接池

{service="checkout"} |= "connection pool exhausted"

关联 日志管道 的解析规则;确认 trace_id 字段在采集层注入。

LogQL:Redis 超时

{service="checkout"} |~ "redis.*timeout|i/o timeout"

关联 日志管道 的解析规则;确认 trace_id 字段在采集层注入。

LogQL:部署标记

{service="checkout"} |= "config reload"

关联 日志管道 的解析规则;确认 trace_id 字段在采集层注入。

LogQL:结构化字段

{service="checkout"} | json | pool_wait_ms > 500

关联 日志管道 的解析规则;确认 trace_id 字段在采集层注入。

期望命中(合成日志行):

{"level":"error","service":"checkout","trace_id":"7f3a9c2e4b1d8f0a6e5c4b3a29180716","msg":"redis: connection pool exhausted","pool_wait_ms":843}

若未命中:记为可观测性盲区——补 redis client span event。


六、Profile 与内核(T+30 — T+45)

6.1 Pyroscope/Parca

对照 12-profiling16 Continuous Profiling

# 虚构 CLI:拉取 15min CPU profile
parca query --pod=checkout-7d8f9c --range=15m --profile-type=cpu

本剧本根因为 I/O 等待,CPU 火焰图不应热点在 json.Marshal——若热点在 GC 则转剧本 C。

6.2 bpftrace(排除内核/network)

bpftrace -e 'kprobe:tcp_connect { @ = hist(nsecs); } interval:s:5 { exit(); }'

连接池问题通常在用户态日志已暴露;内核阶段用于剧本 B。


七、Events 与根因确认(并行 T+25 — T+40)

kubectl rollout history 显示 revision 42 在 T-45min 部署。configmap/checkout-redismaxclients 100。根因:配置回滚错误导致 Redis 连接上限骤降。


八、缓解与修复

优先级 动作 命令
P0 回滚 checkout-redis CM kubectl rollout undo deployment/checkout-redis
P0 熔断可选 应用层 circuit breaker 开关
P1 扩容 kubectl scale deployment/checkout --replicas=16

缓解后观察 18-slo 面板 30 分钟,Burn Rate 回落。


九、主剧本完整时间线(分钟级)

T 动作 工具 系列参考
0 Ack Page PagerDuty 19-alerting
5 RED Grafana 03-metrics
12 按 instance PromQL Prometheus 06-prometheus
18 Tempo 慢 trace Grafana 10-traces
25 Loki trace_id Loki 08-logs
35 CM 变更 kubectl 13-events
42 回滚 kubectl
75 SLO 恢复 Grafana 18-slo

十、剧本 A:MySQL 慢查询(初级)

注入:去掉索引 ALTER 或 chaos 注入延迟。

步骤 1:基线 p99

histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="checkout"}[5m])) by (le))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 2:按 instance

histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="checkout"}[5m])) by (le, instance))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 3:按 endpoint

histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="checkout",endpoint="/api/checkout/submit"}[5m])) by (le))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 4:错误率

sum(rate(http_requests_total{service="checkout",status=~"5.."}[5m])) / sum(rate(http_requests_total{service="checkout"}[5m]))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 5:Redis 客户端

histogram_quantile(0.99, sum(rate(redis_command_duration_seconds_bucket{service="checkout"}[5m])) by (le, command))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 6:连接池

redis_pool_connections_waiting{service="checkout"}

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 7:Burn Rate 1h

slo:checkout:burnrate1h

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

步骤 8:下游 payment

histogram_quantile(0.99, sum(rate(http_client_duration_seconds_bucket{service="checkout",peer="payment"}[5m])) by (le))

在 Grafana Explore 执行上述表达式,时间范围设为告警触发前后 30 分钟。记录中位数与峰值,写入 Incident 时间线(见 incident-timeline.svg)。

Trace:mysql_query span 3s。Log:MySQL server has gone away。Profile:CPU 正常。根因:全表扫描占满连接池。


十一、剧本 B:DNS 超时(中级)

Metric:错误率升、latency 正常。Trace:无 entry span。Log:无应用错误。用 17-kernel-tracing

bpftrace -e 'uprobe:/usr/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo
  /@[comm] = hist(nsecs);/'

根因:CoreDNS 上游不可达。教训:用户态”正常”时查内核/DNS。


十二、剧本 C:JVM Full GC(中级)

周期性 p99 尖峰每 30min。16-continuous-profiling 对比 heap:

# 尖峰前 vs 尖峰时 byte[] 持有量(虚构对比表)
正常: 120MB
尖峰前: 890MB

根因:Kafka consumer max.poll.records 过大。


十三、Game Day 演练模板

## Game Day INC-DRILL-001
- 目标:30 分钟内完成主剧本 T+0 到缓解
- 角色:Commander / Ops / Comms
- 注入:redis maxclients patch
- 通过标准:Burn Rate Page < 5min ack; 根因文档化
- 失败项写入 reliability backlog

22-chaos 对照:混沌实验应触发同等告警。


十四、事故后可观测性审计

问题 本次 改进
Page 早于用户投诉?
trace_id 贯穿 Logs?
连接池等待可日志化? 部分 加 span event
变更 45min 内关联? Events 面板

十五、工程坑点

坑点 1

现象:签合同前未确认默认保留期——上线后发现仅 7 天。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 2

现象:未做 Trace 数据量 POC——按数据量计费时账单超预期。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 3

现象:私有化部署内核版本不支持 eBPF——DeepFlow 功能降级。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 4

现象:以为 OTel 兼容等于可无缝迁出——专有 attribute 未映射。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 5

现象:多租户未配 hard limit——单租户打爆共享存储。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 6

现象:Java Agent 与 OTel SDK 双埋点——存储翻倍。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 7

现象:告警直接 Page CPU 阈值——与 SLO 脱节。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 8

现象:未测迁出 API 吞吐——PB 级导出需数月。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 9

现象:信创环境未 POC Agent——麒麟内核 BTF 缺失。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 10

现象:Dashboard 依赖厂商专有查询——锁定查询层。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 11

现象:采样率在控制台改错——0 与 0.01 混淆。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 12

现象:双写 Collector 单实例——下游慢拖垮全局。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 13

现象:未记录计量口径——账单争议无证据。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 14

现象:只用 demo 环境评估——与生产流量模型不符。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。

坑点 15

现象:忽略跨 AZ 流量费——对象存储 egress 隐性成本。

根因:选型或治理流程跳过 POC/合同/Runbook 环节。

修复:纳入落地清单;事故后写入 reliability backlog。


十六、工具箱清单

阶段 工具 链接
Alert PagerDuty + AM 19-alerting
Metrics Grafana RED 03, 06
Trace Tempo/Jaeger 10-traces
Log Loki 08, 09
Profile Parca/Pyroscope 12, 16
Kernel bpftrace 17
Events K8s + 变更 13-events
网络 DeepFlow/Hubble 15-network-obs

十七、落地清单

# 检查项 负责人 状态
1 是否列出数据出境/等保/信创硬约束? SRE/架构 待办
2 是否完成 OTLP 双写 30 天 POC? SRE/架构 待办
3 是否文档化计量口径(探针数/GB/Active Series)? SRE/架构 待办
4 是否测试历史数据迁出吞吐? SRE/架构 待办
5 是否对齐 SLO Burn Rate 告警路由? SRE/架构 待办
6 是否配置多租户 hard limit? SRE/架构 待办
7 是否统一 trace_id 贯穿 Logs/Traces? SRE/架构 待办
8 是否 Runbook 链到稳定 URL? SRE/架构 待办
9 是否 Game Day 演练主剧本? SRE/架构 待办
10 是否记录 TCO 假设(机器/人力/超额)? SRE/架构 待办
11 是否评估 LGTM 与托管曲线交叉点? SRE/架构 待办
12 是否审查高基数 label 治理? SRE/架构 待办
13 是否 Chaos 对照告警盲区? SRE/架构 待办
14 是否 PII 清洗在 Collector? SRE/架构 待办
15 是否 retention 与 SLO 窗口对齐? SRE/架构 待办

十八、关键概念回顾


十九、下一步

排障能力验证后,用 自建 vs 托管 评估平台 TCO。


上一篇中国厂商对比

下一篇自建 vs 托管

时间线扩展 1(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 2(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 3(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 4(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 5(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 6(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 7(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 8(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 9(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 10(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 11(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 12(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 13(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 14(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 15(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 16(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 17(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 18(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 19(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 20(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 21(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 22(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 23(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 24(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 25(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 26(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 27(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 28(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 29(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 30(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 31(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 32(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 33(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 34(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 35(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 36(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 37(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 38(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 39(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 40(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 41(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 42(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 43(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 44(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 45(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 46(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 47(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 48(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 49(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 50(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 51(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 52(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 53(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 54(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 55(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 56(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 57(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 58(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 59(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 60(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 61(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 62(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 63(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 64(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 65(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 66(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 67(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 68(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 69(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 70(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 71(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 72(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 73(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 74(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 75(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 76(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 77(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 78(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 79(T+60min)

动作:事后审计

细节:填写可观测性盲区表;链到 22-chaos backlog。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 80(演练复盘)

动作:Game Day 纪要模板

细节:角色、gap、owner、due date。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 81(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 82(T+10min)

动作:检查 redis_exporter

细节redis_connected_clients vs maxclients

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 83(T+14min)

动作:Tempo TraceQL

细节{ resource.service.name = "checkout" && duration > 1s }

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 84(T+22min)

动作:Loki pattern

细节:{service=“checkout”} | json | pool_wait_ms > 500

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 85(T+28min)

动作:Events 面板

细节:关联 ConfigMap rollout 与 13-events

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 86(T+33min)

动作:缓解:scale

细节kubectl scale deployment/checkout --replicas=16 临时扩容。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 87(T+38min)

动作:回滚 redis CM

细节kubectl rollout undo deployment/checkout-redis

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 88(T+50min)

动作:SLO 恢复观察

细节:Burn Rate 回落至 < 1× 持续 30min。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

时间线扩展 1(T+8min)

动作:按 endpoint 分解 PromQL

细节:确认是否仅 /api/checkout/submit 异常。

系列交叉:对照 18-slo 错误预算消耗与 19-alerting Page 路由。

参考资料

  1. Google, Site Reliability Engineering, Ch.14, O’Reilly, 2016
  2. PagerDuty, Incident Response Guide, https://response.pagerduty.com/
  3. Google, Site Reliability Workbook, Ch.5, O’Reilly
  4. Prometheus, Alerting Rules, https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
  5. Grafana, Tempo TraceQL, https://grafana.com/docs/tempo/
  6. 本系列 01–22 各篇

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-22 · architecture / observability

可观测性工程

从 Metrics、Logs、Traces 到 Profiling、eBPF、OpenTelemetry 与 SLO 治理,面向中国工程团队的可观测性系统化手册。全 25 篇。


By .