编程语言研究书库

生产环境的监控与排障 — OpenTelemetry、Prometheus、告警与 Runbook

生产环境的监控与排障 — OpenTelemetry、Prometheus、告警与 Runbook

这一章把第 12 章的演示栈升级成生产回路。 第 12 章答"怎么看"; 本章答三个更硬的问题:埋点怎么标准化(OTel)、什么时候该吵醒人 (告警哲学 + 规则)、吵醒之后怎么办(runbook)。主线例子:orders-service 与 payments-service 两个服务,从埋点到告警到 runbook 全链路。

1. 可见性从埋点开始:OpenTelemetry

书里的立场很硬:如果服务发不出有意义的遥测数据,什么 dashboard 和告警 都讲不出真实故事1。早期微服务时代各用各的库(OpenTracing 管追踪、 OpenCensus 管指标),如今合并成 OpenTelemetry(OTel)——开源、厂商中立的 埋点标准,统一收 traces、metrics、logs。三个积木1:

积木干什么
Instrumentation 库嵌进应用代码,自动抓 spans、时延、指标(常见框架开箱即用)
OpenTelemetry Collector接收、处理、导出遥测到各后端(Jaeger、Prometheus、云服务)
Exporters定义数据发给谁、怎么发

三段拼成一条管道:采集与存储/可视化解耦——换后端不用改应用1。

Trace 的概念正式化: 一次请求穿过分布式系统全程是一个 trace, 其中每个服务执行的一段是一个 span;trace 就是 span 的树, 带上时延和上下文传播。请求慢了,你能精确定位是哪个服务、哪个调用拖的2。

2. 采集与可视化:Prometheus + Grafana 上 K8s

指标的采集可视化仍是 Prometheus + Grafana 这对搭档(第 12 章单机版在 K8s 上以 observability 命名空间里的工作负载形式部署:Prometheus 抓指标、 Grafana 出 dashboard,还有现成的预定义 dashboard 可导入)3。 埋点侧的最佳实践(书里的专节)是五条:尽早埋点(开发初期就上,别等出问题)、 服务命名标准化(一致的命名才有可拼的 dashboard 和 trace)、记录业务上下文 (技术指标之外带上用户/交易标识)、指标与追踪关联(时延尖峰能跳到具体 span)、 优先 OTLP 导出(互操作性最好)4。落到代码上,时延用 histogram 记录 (orders_request_seconds / payments_request_seconds),后面 p95 告警的 histogram_quantile 就靠它的 bucket5。选指标的思路我们再补一条书外的: RED 方法(速率/错误/时延)是微服务指标的常用最小集(补充,不在书里)。

3. 告警的哲学:先立规矩,再写规则

书里的告警观值得整段接住6:

告警只在该行动时吸引人注意。不是每个偏离基线的事都值得一条呼叫或 Slack 消息。最好的告警是预测性的,而不是反应性的——它预警的是"即将 影响用户的趋势",而不是"已经影响的既成事实"。

告警疲劳比漏掉一个事件更糟:太多噪音导致麻木,太少又留盲区。目标是平衡: 对真实用户痛点的症状告警,诊断交给 dashboard 和日志6。

三条准则6:

  1. 对症状告警,不对原因——用户在乎的是响应慢,不是哪个容器 CPU 满了;
  2. 明确归属——每条告警都要有负责处理的团队或个人;
  3. 带上上下文——好的告警消息直接附 dashboard 或 runbook 链接。

机制层面:告警就是定期求值的 PromQL 表达式,条件持续成立一段时间, Prometheus 就触发告警。例子口径:error rate > 5% 持续 2 分钟、 p95 时延超过 1 秒6。

4. 告警规则与路由

规则写成 YAML,四条字段各司其职7:

groups:
  - name: service_alerts
    interval: 30s
    rules:
      - alert: HighErrorRate
        expr: rate(orders_errors_total[2m]) / rate(orders_requests_total[2m]) > 0.05
        for: 1m                                  # 持续 1 分钟才触发(防抖动)
        labels: { severity: warning, service: orders-service }   # 路由用
        annotations:                                             # 给人看
          summary: "High error rate in orders-service"
          description: "Error rate above 5% for more than 1 minute."
      - alert: HighLatency
        expr: histogram_quantile(0.95, sum(rate(orders_request_seconds_bucket[2m])) by (le)) > 1
        for: 1m
        labels: { severity: critical, service: orders-service }
      - alert: PaymentsLatency
        expr: histogram_quantile(0.95, ...) > 0.8     # payments 阈值 800ms
  • expr 求值的 PromQL;for 条件要持续多久才算数(滤掉毛刺);
  • labels(severity/service)给 Alertmanager 做路由;
  • annotations 是通知里给人读的话;
  • 规则文件经 ConfigMap 挂载进 Prometheus,rule_files 自动加载目录下 所有 *.yml——规则可以和 Prometheus 二进制独立版本化、独立发布; 应用后访问 Prometheus 的 /rules 确认加载与求值状态7。

触发之后由 Alertmanager 接手路由:按 label 决定发给哪个团队、走邮件还是 Slack、要不要聚合与静默8。

5. Runbook:把信号变成操作

告警本身只是信号;让它有运营价值的是上下文——"接下来该做什么"的知识。 Runbook 就是那份文档:简洁、结构化,告诉值班的人(老手或新人)怎么排查、 怎么处置。 runbook 弥合"检出"与"解决"之间的缝9。

六要素(照单接住)9:

  1. 摘要(这条告警/问题是什么)
  2. 影响(对用户或系统意味着什么)
  3. 立即检查(确认或排除的第一步动作)
  4. 可能原因(这条告警常见的触发原因)
  5. 修复步骤(缓解与根治)
  6. 参考(dashboard、trace、相关文档链接)

书里给了两个完整样例。其一"orders-service 错误率高":影响=用户结账/支付失败; 立即检查=确认告警→打开 Orders & Payments dashboard 看量/时延/错误率面板→ 查 payments-service 是否也在报错;可能原因=两服务间网络问题、最近的部署 引入 bug、数据库或外部 API 超时;修复=查日志找堆栈→是部署引入的就回滚→ 偶发则重启 Pod→缓解后在 dashboard 验证恢复;参考=Grafana dashboard + Jaeger trace10。

6. 两系告警的分工与运营纪律

Prometheus 告警 vs Grafana 告警的对照(书里表 18.1 的要点)11:

维度Prometheus + AlertmanagerGrafana Unified Alerting
定义YAML 规则文件可视化/声明式(界面里)
范围全部指标,全局通常按 dashboard 或团队
路由Alertmanager 集中路由Grafana 内联系点
场景生产级告警dashboard 级/实验性告警

实践上很多团队两者并用:关键告警走 Prometheus(要版本化),辅助性、 提升态势感知的走 Grafana11。

收尾的运营纪律(书末,态度鲜明)12:

好的可观测性设置不是永远不变的,而是被定期审查、测试和打磨的。 把告警和 runbook 当作应用的活组件对待,而不是静态文档。

具体两条习惯:每次事故复盘都问"检出够不够早、告警里上下文够不够"; 定期故意触发测试告警、做受控故障演练——让告警通道和 runbook 在真出事前 就被验证过12。

7. 作者的判断与证据

  • **"对症状不对原因"**是 Google SRE 系的核心告警哲学,书里与"告警疲劳" 的权衡一起给出,论证完整6。
  • for 字段防抖动、labels 路由、annotations 给人看——字段级分工 是实操细节,可信7。
  • Runbook 六要素 + 两个成例是本章最可直接搬用的部分,结构本身就是 检查表910。
  • Prometheus 管关键告警、Grafana 管辅助告警的分工建议符合行业常见实践, 但属于经验之谈,非定论11。

判断(我们的,不是书里的): 本章其实讲的是"自动化的最后一里": 编排器(14–17 章)解决了"系统自己恢复",本章解决"恢复不了时人怎么接管"。 而 runbook 文化的深层含义是把个人排障经验组织化—— 没有 runbook 的团队,告警只是叫醒一个人;有了 runbook,叫醒的是一套 被验证过的集体记忆。AI 运维(第 19 章)接的正是这个位置的下一站。 如果错,会错在: runbook 在AI agent 能自动排障的未来可能贬值为 "训练材料";但"症状告警 + 明确归属 + 上下文"的告警设计原则, 对人和 AI 接收者同样成立——那一层不会过时。

8. 边界与局限

  • 本章示例的 Prometheus/Grafana 部署在 K8s 上,但对告警哲学与 runbook 的讨论平台无关——这是好事。
  • 没有覆盖:SLO/错误预算的定量框架(只出现 p95 等概念)、on-call 轮值 制度、事故指挥体系(incident command)。
  • 通知渠道(邮件/Slack/PagerDuty 的具体配置)一带而过,以 Alertmanager 路由概念为主。
  • PromQL 的具体函数(rate/histogram_quantile)只到示例级,系统学习要查 Prometheus 官方文档。

9. 可带走的

  1. 可见性从埋点开始;OTel 三积木:库、Collector、exporters——采集与后端解耦1。
  2. trace = span 的树;慢请求定位到具体服务/调用2。
  3. 时延用 histogram 记,p95 告警靠 bucket5。
  4. 对症状告警不对原因;告警疲劳比漏报更糟6。
  5. 规则四字段:expr/for(防抖动)/labels(路由)/annotations(给人)7。
  6. 规则走 ConfigMap + rule_files,与 Prometheus 独立版本化7。
  7. runbook 六要素:摘要/影响/立即检查/可能原因/修复/参考9。
  8. 关键告警 Prometheus、辅助告警 Grafana,两者并用11。
  9. 告警和 runbook 是活组件:事故后复盘、定期演练12。

10. 原文地图

主题原书章原文位置
埋点是起点Technical requirementstext/198-fm-technical-requirements.txt:36(搜「Instrumenting」) · text/198-fm-technical-requirements.txt:40(搜「real story」)
OTel 三积木Technical requirementstext/198-fm-technical-requirements.txt:43(搜「OpenTracing」) · text/198-fm-technical-requirements.txt:46(搜「three key building blocks」) · text/198-fm-technical-requirements.txt:51(搜「Collector」) · text/198-fm-technical-requirements.txt:55(搜「Exporters」)
trace/span 定义Technical requirementstext/198-fm-technical-requirements.txt:59(搜「distributed tracing」) · text/198-fm-technical-requirements.txt:63(搜「tree of spans」)
指标采集可视化节Collecting and visualizing metrics with Prometheus and Grafanatext/199-fm-collecting-and-visualizing-metrics-with-promethe.txt:29(搜「Collecting and visualizing」) · text/199-fm-collecting-and-visualizing-metrics-with-promethe.txt:9(搜「Best practices」)
告警哲学三准则Defining alerts and runbookstext/200-fm-defining-alerts-and-runbooks.txt:45(搜「purpose of alerts」) · text/200-fm-defining-alerts-and-runbooks.txt:49(搜「predictive」) · text/200-fm-defining-alerts-and-runbooks.txt:55(搜「alert fatigue」) · text/200-fm-defining-alerts-and-runbooks.txt:60(搜「symptoms」) · text/200-fm-defining-alerts-and-runbooks.txt:61(搜「ownership」) · text/200-fm-defining-alerts-and-runbooks.txt:62(搜「context」)
规则四字段与三例Defining alerts and runbookstext/200-fm-defining-alerts-and-runbooks.txt:86(搜「HighErrorRate」) · text/200-fm-defining-alerts-and-runbooks.txt:100(搜「histogram_quantile」) · text/200-fm-defining-alerts-and-runbooks.txt:137(搜「expr」) · text/200-fm-defining-alerts-and-runbooks.txt:163(搜「rule_files」)
Alertmanager 路由Defining alerts and runbookstext/200-fm-defining-alerts-and-runbooks.txt:180(搜「Connecting Prometheus to Alertmanager」)
runbook 六要素Defining alerts and runbookstext/200-fm-defining-alerts-and-runbooks.txt:305(搜「practical runbooks」) · text/200-fm-defining-alerts-and-runbooks.txt:317(搜「Summary」) · text/200-fm-defining-alerts-and-runbooks.txt:326(搜「error rate」) · text/200-fm-defining-alerts-and-runbooks.txt:342(搜「roll back」)
两系告警对照Defining alerts and runbookstext/200-fm-defining-alerts-and-runbooks.txt:464(搜「versus」) · text/200-fm-defining-alerts-and-runbooks.txt:470(搜「YAML rule files」) · text/200-fm-defining-alerts-and-runbooks.txt:480(搜「use both」)
运营纪律Defining alerts and runbookstext/200-fm-defining-alerts-and-runbooks.txt:487(搜「Operational readiness」) · text/200-fm-defining-alerts-and-runbooks.txt:495(搜「living components」) · text/201-fm-summary.txt:4(搜「Review alerts」) · text/201-fm-summary.txt:7(搜「Simulate failures」)

Footnotes

  1. 出处:「Technical requirements」的埋点节(text/198-fm-technical-requirements.txt:37,搜「visibility starts」;:40,搜「real story」;:43,搜「OpenTracing」;:45,搜「OpenTelemetry」;:46,搜「three key building blocks」)。 ↩ ↩2 ↩3 ↩4

  2. 出处:「Technical requirements」的追踪节(text/198-fm-technical-requirements.txt:60,搜「single request」;:63,搜「tree of spans」;:71,搜「contributes to the latency」)。 ↩ ↩2

  3. 出处:「Collecting and visualizing metrics with Prometheus and Grafana」的章节开头(text/199-fm-collecting-and-visualizing-metrics-with-promethe.txt:29,搜「Collecting and visualizing」)与预定义 dashboard 段(text/199-fm-collecting-and-visualizing-metrics-with-promethe.txt:529,搜「pre-defined」)。 ↩

  4. 出处:「Collecting and visualizing metrics with Prometheus and Grafana」的埋点最佳实践小节(text/199-fm-collecting-and-visualizing-metrics-with-promethe.txt:9,搜「Best practices for instrumentation」;:14,搜「Instrument early」)。原文:五条建议——尽早埋点;服务命名标准化;记录业务上下文;指标与追踪关联;优先 OTLP 导出。 ↩

  5. 出处:「Collecting and visualizing metrics with Prometheus and Grafana」的埋点代码(text/199-fm-collecting-and-visualizing-metrics-with-promethe.txt:146,搜「orders_request_seconds」;:222,搜「histogram (orders_request_seconds)」)与告警规则(text/200-fm-defining-alerts-and-runbooks.txt:100,搜「histogram_quantile」)。原文:orders/payments 各用 Histogram 记录请求时延;p95 告警用 histogram_quantile 按 bucket 聚合。 ↩ ↩2

  6. 出处:「Defining alerts and runbooks」第 45–66 段(text/200-fm-defining-alerts-and-runbooks.txt:46,搜「requires action」;:49,搜「predictive」;:54,搜「more than 2 minutes」;:55,搜「alert fatigue」;:60,搜「symptoms」;:61,搜「ownership」;:62,搜「context」)。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6

  7. 出处:「Defining alerts and runbooks」第 68–178 段(text/200-fm-defining-alerts-and-runbooks.txt:86,搜「HighErrorRate」;:100,搜「histogram_quantile」;:113,搜「PaymentsLatency」;:130,搜「exceeds 5%」;:137,搜「expr」;:146,搜「ConfigMap」;:163,搜「rule_files」;:168,搜「9090/rules」)。 ↩ ↩2 ↩3 ↩4 ↩5

  8. 出处:「Defining alerts and runbooks」的 Alertmanager 节(text/200-fm-defining-alerts-and-runbooks.txt:180,搜「Connecting Prometheus to Alertmanager」;:178,搜「right team」)。 ↩

  9. 出处:「Defining alerts and runbooks」第 305–323 段(text/200-fm-defining-alerts-and-runbooks.txt:309,搜「runbook is」;:312,搜「close the gap」;:316,搜「contains the following」)。 ↩ ↩2 ↩3 ↩4

  10. 出处:「Defining alerts and runbooks」第 324–364 段(text/200-fm-defining-alerts-and-runbooks.txt:326,搜「exceeded 5%」;:342,搜「roll back」;:346,搜「Grafana dashboard」)。 ↩ ↩2

  11. 出处:「Defining alerts and runbooks」第 464–485 段(text/200-fm-defining-alerts-and-runbooks.txt:468,搜「Aspect」;:470,搜「YAML rule files」;:476,搜「Production-grade」;:480,搜「use both」)。 ↩ ↩2 ↩3 ↩4

  12. 出处:「Defining alerts and runbooks」第 487–495 段与「Summary」(text/200-fm-defining-alerts-and-runbooks.txt:495,搜「living components」;text/201-fm-summary.txt:4,搜「Review alerts」;:3,搜「Simulate failures」)。 ↩ ↩2 ↩3

On this page