CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
可观测性入门/课时/仪表盘设计
RawBlame
课时目录12 节

可观测性入门

  1. 01可观测性三支柱
  2. 02指标与 SLI
  3. 03结构化日志
  4. 04分布式链路追踪
  5. 05插桩与埋点
  6. 06监控与告警
  7. 07遥测与 OpenTelemetry
  8. 08Spring 可观测性
  9. 09SLO 与错误预算
  10. 10仪表盘设计
  11. 11故障排查流程
  12. 12综合练习

仪表盘设计

RED/USE 方法;Grafana 思路。

25 分钟

仪表盘设计

这一课你将能做到

  1. 用 RED(Rate / Errors / Duration)为判题接口设计最小值班面板集,每个面板回答一个固定问题
  2. 用 USE(Utilization / Saturation / Errors)检查 CPU、内存、磁盘、Kafka 队列等资源瓶颈
  3. 规划 on-call 看板的分层结构:症状 → SLO → 依赖 → 资源,并留下 drill-down 路径和 runbook 链接

为什么要学

仪表盘若变成「图表墙」——50 个面板堆在一屏,值班时反而找不到「用户是否受伤」。典型翻车:新人收到告警,打开 Grafana 看到满屏绿色曲线,不知道先看哪个,5 分钟后才定位到 RED 面板,止血时间被白白浪费。

好的面板回答固定问题:用户是否痛?痛多久了?可能在哪一层?预算还剩多少? 本课讲设计原则;Grafana 变量、模板、点击操作见 prom-grafana。本课刻意不克隆那门课的操作步骤,而补齐 观测心智与布局。面试里「RED 和 USE 的区别」「怎么设计一个值班看板」是高频题。

先建立图像

方法适用三要素判题系统示例
RED请求驱动服务Rate(速率)、Errors(错误率)、Duration(延迟分布)提交接口 QPS、5xx 率、P99 延迟
USE节点/容器/队列等资源Utilization(利用率)、Saturation(饱和度)、Errors(资源错误)Pod CPU%、Kafka consumer lag、磁盘 IO 错误
判题 backend 建议的 Grafana 行布局(从上到下):

Row 1  RED   — 提交接口 RPS、5xx%、P50/P99(http_server_requests)
              用户是否痛?痛多严重?
Row 2  SLO   — 30 天可用率、剩余错误预算、burn rate 趋势
              承诺还剩多少余量?
Row 3  依赖  — MySQL 连接池、Kafka consumer lag、Redis 命中率
              下游是不是瓶颈?
Row 4  JVM   — 堆内存、GC 暂停、线程数(解释用,不替代 RED)
              应用内部有没有异常?
Row 5  USE   — 容器 CPU/内存/磁盘、网络吞吐(容量线索)
              资源是不是快满了?

跟着做

步骤 1:为判题接口画 RED 三格(最小值班面板)

纸上三格,每格一个 PromQL:

格 1:Rate(QPS)
  sum(rate(http_server_requests_seconds_count{uri="/api/judge/submissions"}[5m]))
  回答:现在多少人在提交?

格 2:Errors(5xx 率)
  sum(rate(http_server_requests_seconds_count{uri="/api/judge/submissions",status=~"5.."}[5m]))
  /
  sum(rate(http_server_requests_seconds_count{uri="/api/judge/submissions"}[5m]))
  回答:用户在报错吗?错误率多少?

格 3:Duration(P99 延迟)
  histogram_quantile(0.99,
    sum(rate(http_server_requests_seconds_bucket{uri="/api/judge/submissions"}[5m])) by (le))
  回答:最慢的 1% 用户等了多久?

应得到:任何新服务上线前的「最小可值班面板」——三格足够判断「用户是否受伤」。

步骤 2:为判题 worker 补 USE 检查清单

对某个 worker Pod:

Utilization:
  - CPU 使用率:container_cpu_usage_seconds_total
  - 内存使用率:container_memory_working_set_bytes / limit

Saturation:
  - Kafka consumer lag:kafka_consumer_fetch_manager_records_lag
  - 线程池队列深度:executor_queued_tasks

Errors:
  - 磁盘 IO 错误:node_disk_io_errors_total
  - 网卡丢包:node_network_receive_errs_total

应得到:资源问题有标准问法,而不是随便加图。

步骤 3:设计变量与下钻路径

约定 Grafana 变量:

变量:
  $application: 服务名(coderoadmap-backend / judge-worker)
  $uri: 接口路径(模板变量,从 http_server_requests_seconds_count 的 uri 标签动态拉取)
  $pod: Pod 实例(多副本环境定位单个实例)

下钻路径:

总览面板(所有服务 RED 汇总)
  → 点击 coderoadmap-backend → 单服务 RED 面板
    → 点击 /api/judge/submissions → 单接口 RED 面板
      → 面板注释:「P99 突增时,复制 traceId 到 Jaeger 查慢链路」

写一句面板注释:「P99 突增时:复制 traceId 示例查询 → 见 obs-incident」。

步骤 4:把告警与面板对齐

打开 obs-monitoring 的 Symptom 告警,确保对应面板就在 on-call 首页第一行:

JudgeSubmissionHighErrorRate(page 告警)
  → 对应 Row 1 的 Errors 面板
  → 告警注解里直接放面板 URL:https://grafana/d/judge-red?var-uri=/api/judge/submissions

告警负责叫醒,面板负责 30 秒确认。

步骤 5:做「删图」练习

列出你想加的 15 个图:

候选:HTTP 4xx 率、HTTP 5xx 率、QPS、P50、P95、P99、平均延迟、JVM 堆、
      JVM 非堆、GC 次数、GC 暂停、线程数、CPU、内存、磁盘 IO、网络吞吐、
      Kafka lag、MySQL 连接池、Redis 命中率、错误预算剩余、burn rate

强制删到 ≤ 10:

保留:QPS、5xx 率、P99、错误预算剩余、burn rate、Kafka lag、MySQL 连接池、CPU、内存
删除:P50/P95(P99 已覆盖长尾)、平均延迟(被 P99 替代)、GC 细节(JVM 大盘已含)、
      磁盘 IO(低频)、网络吞吐(云厂商监控已有)

删除标准:不能改变故障决策的图优先删。应得到:少而精的布局,而不是收藏夹式仪表盘。

步骤 6:核对标签与 Spring 侧一致

确认 application、region 等标签来自 obs-spring 的配置;K8s 集群层 USE 可对照 prom-k8s。标签不一致,面板变量就无法工作。

步骤 7:给判题系统画完整看板结构

Dashboard: coderoadmap-judge-overview(on-call 首页)

Row 1 RED(判题提交接口)
  Panel 1: QPS(rate 5m)
  Panel 2: 5xx 率(%)
  Panel 3: P99 延迟(秒)

Row 2 SLO 与预算
  Panel 4: 30 天可用率(当前值 + 趋势线)
  Panel 5: 剩余错误预算(时间/次数)
  Panel 6: burn rate(1h 和 6h 双窗口)

Row 3 依赖健康
  Panel 7: MySQL 连接池(活跃/等待)
  Panel 8: Kafka consumer lag
  Panel 9: Redis 命中率

Row 4 资源(USE)
  Panel 10: Pod CPU/内存使用率

顶部变量:$application, $uri, $pod
底部注释:告警 runbook 链接、Jaeger 查询入口、值班手册链接

讲清楚要点

  1. 值班首先关心用户,所以 RED 应置于首页最上方——5xx 率上升 10 秒内必须能看到,不需要滚动。
  2. 资源问题是因果线索,所以 USE 在下、作解释,不替代 Symptom——CPU 高不等于用户痛,用户痛了才往下查资源。
  3. 单位混乱会误判,所以延迟统一秒或毫秒,比率统一 0-1 或百分比——一个面板里 P99 用秒、另一个用毫秒,值班时会算错。
  4. 人短时记不住上下文,所以面板注释要链 runbook——「这个图异常时怎么办」写在面板描述里,不要让 on-call 去翻 Wiki。
  5. SLI/SLO 是承诺,所以预算面板应可见——见 obs-slo;发布前先看预算余量。
  6. 不同观众需求不同,on-call 看板 ≠ 容量规划看板——值班要实时症状,容量规划要看趋势和资源水位,分两个 dashboard。
  7. 下钻靠标签,所以指标基数与命名纪律决定面板能不能做细——见 obs-metrics;标签乱了,变量模板就失效。

你可能会懵的地方

  • RED 和 USE 能否用在同一个服务? 能。RED 看服务外部表现(用户视角),USE 看它跑在其上的资源(机器视角)。先 RED 后 USE——用户痛了,再往下查是不是资源瓶颈。

  • 只要 Grafana 导入官方 JVM 大盘就够了吗? JVM 大盘有用,但不能回答「用户 API 是否失败」。JVM 指标是因果线索,不是 Symptom。先 RED,再 JVM。

  • P99 面板是否要和 Trace 强链? 最好提供跳转说明或示例查询。否则指标告诉你「慢」,你仍不知「哪一跳慢」。在面板描述里写:「P99 突增时,复制 traceId 到 Jaeger 查慢链路:http://jaeger/search?traceID=...」

  • 和 prom-grafana 如何分工? 那课:怎么点 Grafana、怎么配变量、怎么导入 dashboard JSON;本课:面板该回答什么问题、如何分层、如何删繁就简。前者是「怎么操作」,后者是「为什么这么设计」。

  • 多副本环境面板怎么聚合? 按 application 标签 sum 聚合看整体,用 $pod 变量过滤看单实例。不要把 10 个 Pod 画 10 条线——看不出整体趋势。异常时再用变量过滤定位具体实例。

错法对照

错法问题正解
50 个面板堆一屏值班找不到重点,止血时间浪费分层布局:RED → SLO → 依赖 → 资源
只看 JVM 大盘,不看 RED资源正常但接口已挂RED 优先,JVM 作解释
延迟用平均值长尾被稀释,1% 坏体验被掩盖P95/P99 + 错误率
面板无注释和链接on-call 不知道下一步查什么面板描述含 runbook 和 drill-down 链接
每个 Pod 画一条线看不出整体趋势,满屏噪音按 application 聚合,变量过滤单实例
单位混乱(秒/毫秒混用)值班时算错数量级全局统一:延迟用秒,比率用百分比

卡点急救

  1. 面板变量 $uri 下拉列表为空:检查指标是否有 uri 标签;确认标签值是模板化的(/api/judge/submissions)而非原始 URL(/api/judge/submissions/12345);在 Prometheus 里手动跑 label_values(http_server_requests_seconds_count, uri) 验证。
  2. P99 曲线出现莫名尖刺:通常是数据稀疏(低流量时段几个慢请求拉高 P99)。调整方向:增大 rate 窗口(如 [5m] 改 [10m]);或在面板上加 min 样本数 过滤(如 count > 10 才显示)。
  3. 面板显示「No data」但 Prometheus 里有指标:检查 Grafana datasource 配置是否指向正确的 Prometheus;检查面板查询的时间范围是否超出 Prometheus 保留期(默认 15 天);检查标签选择器是否拼错(区分大小写)。

面试常问

  • RED 和 USE 是什么?区别在哪? 背这个版本:RED 是请求驱动服务的三要素——Rate(QPS)、Errors(错误率)、Duration(延迟分布),回答「用户是否痛」。USE 是资源视角的三要素——Utilization(利用率)、Saturation(饱和度)、Errors(资源错误),回答「资源是不是瓶颈」。值班流程:先 RED 确认症状,再 USE 查资源根因。判题系统例子:5xx 率上升(RED)→ 发现 Kafka consumer lag 满(USE - Saturation)→ 扩容 worker。

  • 怎么设计一个 on-call 看板? 分层结构:Row 1 RED(症状优先,5 秒内看到用户是否受伤)、Row 2 SLO(预算余量,发布决策依据)、Row 3 依赖(MySQL/Kafka/Redis 健康)、Row 4 资源(JVM/CPU/内存,解释用)。每格回答一个固定问题,面板注释含 runbook 链接。变量支持 drill-down:application → uri → pod。核心原则:少而精,删图到 ≤ 10 个。

  • 为什么延迟要看 P99 而不是平均值? 平均值把长尾稀释:100 个请求 95 个 10ms、5 个 10s,平均值约 510ms 看起来还行,但那 5 个用户已经流失。P99 表示「99% 的请求都低于这个值」,反映最差体验。大流量下 1% 就是每天成千上万次坏体验。工程实践:接口延迟看 P95/P99,告警用 P99 + 错误率。

自测三问

  1. 判题接口的 RED 三格面板各用什么 PromQL?
  2. 为什么 USE 面板放在 RED 下方而不是上方?
  3. 设计面板时,「删图」的标准是什么?举例说明两个可以删的候选。

小结一句话

仪表盘不是图表收藏夹——RED 优先、分层布局、每格回答一个问题,值班时 30 秒定位用户是否受伤。

延伸

  • Grafana:Dashboard 最佳实践
  • The USE Method
  • Google SRE Workbook:Monitoring Dashboards
  • 下一课《故障排查流程》:面板发现异常后,按什么流程快速定位和止血。
加载本节练习…
← 上一课SLO 与错误预算下一课 →故障排查流程