大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
仪表盘设计
这一课你将能做到
- 用 RED(Rate / Errors / Duration)为判题接口设计最小值班面板集,每个面板回答一个固定问题
- 用 USE(Utilization / Saturation / Errors)检查 CPU、内存、磁盘、Kafka 队列等资源瓶颈
- 规划 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 查询入口、值班手册链接
讲清楚要点
- 值班首先关心用户,所以 RED 应置于首页最上方——5xx 率上升 10 秒内必须能看到,不需要滚动。
- 资源问题是因果线索,所以 USE 在下、作解释,不替代 Symptom——CPU 高不等于用户痛,用户痛了才往下查资源。
- 单位混乱会误判,所以延迟统一秒或毫秒,比率统一 0-1 或百分比——一个面板里 P99 用秒、另一个用毫秒,值班时会算错。
- 人短时记不住上下文,所以面板注释要链 runbook——「这个图异常时怎么办」写在面板描述里,不要让 on-call 去翻 Wiki。
- SLI/SLO 是承诺,所以预算面板应可见——见 obs-slo;发布前先看预算余量。
- 不同观众需求不同,on-call 看板 ≠ 容量规划看板——值班要实时症状,容量规划要看趋势和资源水位,分两个 dashboard。
- 下钻靠标签,所以指标基数与命名纪律决定面板能不能做细——见 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 聚合,变量过滤单实例 |
| 单位混乱(秒/毫秒混用) | 值班时算错数量级 | 全局统一:延迟用秒,比率用百分比 |
卡点急救
- 面板变量
$uri下拉列表为空:检查指标是否有uri标签;确认标签值是模板化的(/api/judge/submissions)而非原始 URL(/api/judge/submissions/12345);在 Prometheus 里手动跑label_values(http_server_requests_seconds_count, uri)验证。 - P99 曲线出现莫名尖刺:通常是数据稀疏(低流量时段几个慢请求拉高 P99)。调整方向:增大 rate 窗口(如
[5m]改[10m]);或在面板上加min 样本数过滤(如count > 10才显示)。 - 面板显示「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 + 错误率。
自测三问
- 判题接口的 RED 三格面板各用什么 PromQL?
- 为什么 USE 面板放在 RED 下方而不是上方?
- 设计面板时,「删图」的标准是什么?举例说明两个可以删的候选。
小结一句话
仪表盘不是图表收藏夹——RED 优先、分层布局、每格回答一个问题,值班时 30 秒定位用户是否受伤。
延伸
- Grafana:Dashboard 最佳实践
- The USE Method
- Google SRE Workbook:Monitoring Dashboards
- 下一课《故障排查流程》:面板发现异常后,按什么流程快速定位和止血。