可观测性与运维工程
一个服务变慢了。你打开监控仪表盘:CPU 正常,内存正常,错误率正常。但用户在投诉。
你看着一屏绿色的图表,不知道哪里出了问题。
这是运维工程的核心困境:一个足够复杂的系统,你永远无法”读完它”。你只能通过它主动发出或被动暴露的信号来推断内部状态。运维工程要解决的问题,本质上是认识论的——一个你无法直接观察内部的系统,你怎么知道它是否健康,出了问题你怎么理解它?
这个问题有两代不同的回答。
第一代:监控(Monitoring)。你在部署前就预测会出什么问题,然后在那些位置埋下探针——CPU 超过 90% 就告警,磁盘使用率超过 80% 就告警,ping 失败就告警。这套体系运作了三十年,今天仍然有效:运维简单,案例成熟,工具链(Nagios、Zabbix、Prometheus)围绕这个模型高度优化。它的局限是:它只能发现你预先知道会发生的故障。对于分布式系统里涌现出来的新型故障,它沉默。
第二代:可观测性(Observability)。不再预测故障,而是让系统具备”可被任意提问”的能力——无论是”这次请求慢在哪一跳”,还是”用户 A 的问题和用户 B 的问题有什么共同点”,都能回答。分布式追踪、高基数事件存储、OpenTelemetry 统一仪器标准,是这一代回答的技术形态。代价是:搭建复杂,存储成本高,对团队能力要求更高。
这个系列不预设哪代更好。规模不同,回答不同:一个百人团队运营的产品,Prometheus + Alertmanager + Grafana + Loki 完全够用,引入分布式追踪只会增加运维负担;一个日均千亿次服务调用的平台,不用追踪根本无法定位跨服务的性能退化。
这个系列分两个层次:
经典范式(01-03):理解监控时代的技术逻辑——指标、日志、告警——这些技术今天仍然是基础,不会消失。
可观测性范式(04-08):理解分布式系统时代的新回答——可观测性哲学、分布式追踪、SLO、OpenTelemetry、eBPF 持续分析。
一、目录
本系列共 8 篇文章,分两层:经典范式(01-03)覆盖成熟工具,可观测性范式(04-08)覆盖现代方向。
70-operations/
├── 00-operations-MOC.md ← 本文件
│
├── 10-classical/ # 经典范式(40%)
│ ├── 01-监控:预知故障的经典范式.md ← Nagios / Zabbix / 阈值告警模型
│ ├── 02-指标:时间序列的量化哲学.md ← Prometheus / RED·USE / Alertmanager
│ └── 03-日志:结构化事件的叙事力量.md ← ELK / Loki / 结构化日志设计
│
├── 20-observability/ # 可观测性范式(35%)
│ ├── 04-可观测性:从已知失败到任意提问.md ← 高基数 / wide events / 范式转变
│ ├── 05-分布式追踪:因果链的精确重建.md ← Jaeger / Tempo / 采样策略
│ └── 06-SLO:把可靠性变成数学.md ← SLI·SLO·SLA / error budget / burn rate
│
└── 30-new-paradigms/ # 演进方向(25%)
├── 07-OpenTelemetry:三个信号的统一语言.md ← OTel Collector / OTLP / Exemplar
└── 08-持续分析:eBPF 的零侵入内核洞察.md ← Continuous Profiling / Parca / 火焰图二、概念线索
8 篇文章里反复出现的五条思想脉络。理解这五条线索,就理解了监控与可观测性两代范式的异同与取舍。
mindmap root((运维工程)) 经典范式 监控 预知故障的经典范式 指标 时间序列量化 日志 结构化事件叙事 可观测性范式 可观测性 任意提问的能力 分布式追踪 因果链重建 SLO 可靠性数学化 演进方向 OpenTelemetry 三信号统一 持续分析 eBPF零侵入洞察 核心张力 已知故障 vs 未知故障 预聚合 vs 高基数 信号层次 指标日志追踪 告警人本成本 仪器化代价
线索一:「已知失败 vs 未知失败」——两代范式的认识论根基
监控和可观测性的根本区别,不是工具的新旧,是对”什么问题值得解决”的不同假设。
- 监控的前提(01-监控:预知故障的经典范式):设计监控系统时,你已经对系统有足够的了解,知道哪些组件会失败、以什么方式失败。Nagios 的服务检查本质上是:“我认为这台机器应该能 ping 通,能不到就告警”。这个前提在单体服务和小规模基础设施时成立。
- 可观测性的前提(04-可观测性:从已知失败到任意提问):分布式系统的故障往往是多个正常组件在特定条件下共同产生的涌现行为——没有哪一个组件单独失败,但整体表现出异常。这类故障无法预先埋点,只能在事后通过提问来重建。Charity Majors 的定义:可观测性是系统的一个属性,衡量你能否仅凭外部输出推断任意内部状态。
- 两者的边界:规模是分水岭。单体 + 少量微服务:监控完全足够,追踪是过度投资。数十个微服务 + 高 QPS:指标告诉你”某处慢了”,但无法定位”哪一跳、哪一次请求、哪个用户”;追踪是必要的。
- 新旧共存(07-OpenTelemetry:三个信号的统一语言):OpenTelemetry 把指标、日志、追踪统一为同一套仪器 API,并不是”抛弃指标改用追踪”,而是让三者可以共存并关联——一个告警可以直接链接到触发它的追踪,一条日志可以关联到它所在的 span。
这条线索的终点:选择监控还是可观测性,不是技术品味问题,是对自己系统规模和故障模式的准确判断。错配代价很高:小系统过度投资可观测性,大系统只用监控——都会出问题。
线索二:「预聚合 vs 高基数」——存储模型决定能问什么问题
这条线索解释了为什么指标系统无法替代分布式追踪,以及为什么两者都必须存在。
- 指标的预聚合(02-指标:时间序列的量化哲学):Prometheus 存储的是时间序列——
http_requests_total{method="GET", status="200"}是一个序列,每分钟一个采样点。在数据到达存储之前,已经丢失了请求级别的细节(哪个用户、哪个 IP、请求参数是什么)。预聚合换来了极高的查询效率和可预期的存储成本,但你只能问”过去一小时 P99 是多少”,无法问”哪 1% 的请求是慢的”。 - 高基数事件(04-可观测性:从已知失败到任意提问 / 05-分布式追踪:因果链的精确重建):追踪保存的是每一条请求的完整路径——包含用户 ID、设备类型、版本号、地理位置等任意 tag。这让你可以问”iOS 用户在 2.3.1 版本上的 P99 是否比 Android 高”——这个问题在指标体系里无法回答,因为这些维度在指标被存储时已经被抛弃。代价是存储成本是指标的数十到数百倍,通常需要采样(只保留 1%-10% 的追踪)。
- 日志的位置(03-日志:结构化事件的叙事力量):日志是”完整事件”和”预聚合”之间的中间地带——比指标有更多上下文,比追踪更便宜。结构化日志(JSON)让日志成为可查询的数据,而不只是可搜索的文本。Loki 的模型(只索引 label,日志体不索引)是在成本和查询能力之间找到的平衡点。
- 持续分析的维度(08-持续分析:eBPF 的零侵入内核洞察):持续分析(Continuous Profiling)是第四类信号,回答”时间花在哪里”的问题——不是某次请求花了多少时间(追踪),而是代码中哪些函数累计消耗了最多 CPU。这是指标、日志、追踪都无法回答的问题。
这条线索的终点:每类信号都有它的存储模型和查询边界。工具选型的本质是:你需要回答什么问题,愿意为此付多少存储成本?没有哪种信号全能,组合使用才完整。
线索三:「信号的层次」——指标、日志、追踪、分析各自看见什么
四类信号不是竞争关系,是互补关系。理解它们各自的”认知盲区”,才能在出问题时找到正确的工具。
- 指标回答”多少”和”频率”(02-指标:时间序列的量化哲学):QPS、P99 延迟、错误率、CPU 使用率。指标的核心能力是告警——定义 SLO,当 SLO 被违反时触发告警。无法回答”是哪些请求导致了 P99 升高”。
- 日志回答”发生了什么”(03-日志:结构化事件的叙事力量):每个事件的完整上下文——操作了什么、参数是什么、结果是什么。日志最适合的场景是”已知在某个时间点发生了问题,需要理解细节”。在分布式系统里,单条日志缺少跨服务的因果链。
- 追踪回答”为什么”(05-分布式追踪:因果链的精确重建):一次用户请求在多个服务之间传播的完整路径——每一跳的耗时、调用了哪个数据库、在哪里阻塞。追踪是分布式系统性能排查的唯一有效工具,但它只能重建已经发生的请求,无法聚合回答宏观趋势问题。
- 持续分析回答”时间花在哪里”(08-持续分析:eBPF 的零侵入内核洞察):代码级别的 CPU/内存/IO 热点——不是某次请求,而是持续运行时间内的累计分布。适合定位性能退化的根因(某个函数的调用频率增加),弥补追踪看不到代码内部的盲区。
- 四者的关联(07-OpenTelemetry:三个信号的统一语言):OpenTelemetry 的 Exemplar 机制让指标和追踪可以关联——一个 P99 的数据点可以附带一个追踪 ID,点击即可跳转到那次具体请求的追踪详情。这把”宏观异常发现”和”微观原因定位”连接成一条完整的排查路径。
这条线索的终点:遇到性能问题的排查路径通常是:指标发现异常 → 追踪定位到哪一跳 → 日志理解那次请求的上下文 → 持续分析找到代码热点。四类信号各司其职,缺一不可。
线索四:「告警的人本成本」——叫醒一个工程师值多少钱
告警不是免费的。每一次告警都是在打断一个工程师的认知流,消耗信任,引发告警疲劳。告警系统的设计是关于”什么时候值得打扰人类”的价值判断。
- 基于原因的告警(cause-based)(01-监控:预知故障的经典范式 / 02-指标:时间序列的量化哲学):CPU 超过 90% 告警,磁盘使用率超过 80% 告警——这是监控时代的默认模式。问题是:CPU 高不一定意味着用户受影响(可能是批处理任务),用户受影响也不一定 CPU 高(可能是数据库慢)。原因告警会同时产生误报(CPU 高但用户没问题)和漏报(用户有问题但 CPU 没过阈值)。
- 基于症状的告警(symptom-based)(06-SLO:把可靠性变成数学):不告警”磁盘 80%“,告警”错误率升高,SLO 烧损速率超过阈值”——这直接反映用户体验。Google SRE 的结论是:只对症状告警,不对原因告警;原因只用于故障时的辅助诊断,不用于触发人类介入。
- SLO burn rate 告警(06-SLO:把可靠性变成数学):error budget 是本月允许的总下线时间。burn rate 是当前消耗速率:如果按现在的速率,error budget 会在 1 小时内耗尽,立即告警;如果在 6 小时内耗尽,告警但不紧急;如果在 3 天内耗尽,工单处理。这把告警的紧迫度和实际用户影响精确对应起来。
- 告警疲劳:告警太多等于没有告警——工程师习惯性 silence,真正的故障被忽视。衡量告警质量的指标不是”告警数量”,是”需要人类介入的告警比例”(actionable rate)。一个健康的告警系统里,每次告警都应该需要且值得人类处理。
这条线索的终点:告警设计是关于人的工程,不只是技术配置。从”设阈值”到”定义用户体验边界”,是对告警哲学的根本升级——但前者更简单,后者更准确,两者各有其场景。
线索五:「仪器化的代价」——谁来负责让系统可见
可观测性信号不是凭空而来的,有人必须写代码或配置来让系统”开口说话”。仪器化(instrumentation)的成本,是可观测性落地的最大阻力。
- 手动仪器化(02-指标:时间序列的量化哲学 / 05-分布式追踪:因果链的精确重建):开发者在代码里显式调用 SDK——
metrics.counter.increment()、tracer.startSpan()。优点是精确可控;缺点是代码耦合、工作量大、随着系统演进容易腐烂。 - 自动仪器化(Auto-instrumentation)(07-OpenTelemetry:三个信号的统一语言):OpenTelemetry 的 Java Agent、Python monkey-patching——在不修改应用代码的情况下,拦截框架层的调用(HTTP 请求、数据库查询、消息队列)并自动生成 span。覆盖了 80% 的常见场景,但对自定义业务逻辑无能为力。
- 服务网格的 L4/L7 可见性(云原生与平台工程 MOC 第 07 篇):Istio/Linkerd 在代理层自动采集所有服务间 HTTP/gRPC 调用的指标和追踪——黄金信号(延迟、流量、错误、饱和度)可以做到零代码侵入。但它只看得到服务边界,看不到服务内部。
- eBPF 零侵入仪器化(08-持续分析:eBPF 的零侵入内核洞察):在内核路径上挂载 eBPF 探针,在系统调用边界、网络路径、内存分配点捕获数据——不需要修改应用,不需要重启进程,甚至不需要知道应用是什么语言写的。Pixie、Parca、Pyroscope 都在这个方向上。代价是 eBPF 的调试复杂性和内核版本要求。
- OpenTelemetry 的战略意义(07-OpenTelemetry:三个信号的统一语言):无论用哪种仪器化方式,只要遵循 OTel 规范,后端就可以自由替换(Jaeger、Tempo、Honeycomb、Datadog 都能接)。OTel 把仪器化代价和后端锁定问题分离开来——一次仪器化,永远可迁移。
这条线索的终点:仪器化的演进方向是”成本越来越低,覆盖越来越广”——从手写 SDK 到框架自动注入到内核零侵入,代码侵入度不断降低,可见性不断提升。eBPF 是这个方向的当前终点。
三、经典范式系列(01-03)
监控时代的技术逻辑——这些工具今天仍然是基础。
起点:监控的经典范式
核心问题:Nagios / Zabbix 的设计哲学是什么?它们在什么场景下是最优解,在什么场景下开始失效? 读完之后:理解 agent-based 架构、SNMP、主动/被动检查、阈值告警,理解”预知失败”范式的边界在哪里。
- 01-监控:预知故障的经典范式 — Nagios/Zabbix 架构、agent 模型、服务检查、阈值告警 核心问题:一个 Nagios 检查从发现问题到触发告警通知,中间经历了哪些步骤?为什么这个模型在大规模分布式系统里开始失效? 关联:→ 02-指标:时间序列的量化哲学(指标是对阈值告警的升级,但共享”预知失败”的假设)→ 04-可观测性:从已知失败到任意提问(可观测性是对整个范式的替代)
信号一:指标
核心问题:时间序列数据模型的本质是什么?Prometheus 的 pull 模型和 push 模型各有什么取舍?RED 方法和 USE 方法适用于什么类型的组件? 读完之后:理解 counter / gauge / histogram / summary 四种类型,理解 PromQL 的查询模型,理解如何用指标定义 SLO 并设计告警规则。
- 02-指标:时间序列的量化哲学 — Prometheus 数据模型、RED/USE 方法、PromQL、Alertmanager、Grafana 核心问题:一个 histogram 指标和一个 counter 指标在查询 P99 延迟时,为什么计算方式和精度不同? 关联:→ 06-SLO:把可靠性变成数学(SLO 建立在指标之上)→ 07-OpenTelemetry:三个信号的统一语言(OTel metrics 和 Prometheus metrics 的关系)→ 05-分布式追踪:因果链的精确重建(Exemplar 让指标和追踪关联)
信号二:日志
核心问题:结构化日志和非结构化日志的本质区别是什么?日志级别应该如何设计?Loki 的标签索引模型和 Elasticsearch 的全文索引模型,各自在什么场景下更合适? 读完之后:理解日志作为”事件流”的设计哲学(12-factor app),理解结构化日志的字段设计,理解日志聚合的管道架构(Promtail/Fluentd → Loki/ES)。
- 03-日志:结构化事件的叙事力量 — 结构化日志设计、日志级别语义、Loki vs Elasticsearch、日志管道 核心问题:同样一条”用户登录失败”的日志,结构化和非结构化版本在聚合分析时有什么本质差异? 关联:→ 05-分布式追踪:因果链的精确重建(trace_id 是日志和追踪关联的桥梁)→ 07-OpenTelemetry:三个信号的统一语言(OTel logs 规范)→ Linux 系统 MOC(journald 是 Linux 层面的结构化日志基础)
四、可观测性范式系列(04-08)
分布式系统时代对”如何理解系统”的新回答。
范式转变:可观测性
核心问题:为什么分布式系统让监控范式失效?“可被任意提问”意味着什么,技术上需要什么前提? 读完之后:理解高基数(high cardinality)和高维度(high dimensionality)为什么是可观测性的核心概念,理解 Honeycomb 的 wide events 模型与 Prometheus 的时间序列模型的根本差异。
- 04-可观测性:从已知失败到任意提问 — 高基数、高维度、wide events、探索式分析 核心问题:一个用 Prometheus 完全覆盖的系统,在什么场景下仍然无法回答故障原因?需要什么额外能力? 关联:→ 05-分布式追踪:因果链的精确重建(追踪是可观测性的核心工具)→ 06-SLO:把可靠性变成数学(SLO 定义了”什么算正常”,可观测性帮助理解”为什么异常”)→ 01-监控:预知故障的经典范式(理解与前代的关系)
信号三:分布式追踪
核心问题:trace context 是如何在跨进程调用中传播的?采样策略(头部采样 vs 尾部采样)对追踪系统的架构有什么影响?为什么追踪无法完全替代指标? 读完之后:理解 span / trace / context propagation 的数据模型,理解 Jaeger / Tempo 的存储架构,理解采样率对追踪系统成本和完整性的影响。
- 05-分布式追踪:因果链的精确重建 — trace/span 模型、context propagation、采样策略、Jaeger/Tempo 核心问题:在一个 10 个微服务的系统里,一次用户请求的追踪数据是怎么被拼接成完整路径的?context propagation 在哪里发生? 关联:→ 07-OpenTelemetry:三个信号的统一语言(OTel 是追踪仪器化的事实标准)→ 云原生与平台工程 MOC(服务网格提供无代码侵入的追踪能力)→ 03-日志:结构化事件的叙事力量(trace_id 关联日志和追踪)
可靠性数学:SLO
核心问题:SLI、SLO、SLA 三者的关系和区别是什么?error budget 怎么把”可靠性”从感性判断变成可协商的工程资源?为什么 SLO 告警比阈值告警更准确? 读完之后:理解如何为服务定义有意义的 SLI,理解 error budget burn rate 的计算方式,理解多窗口告警规则的设计逻辑(1h + 6h 窗口组合)。
- 06-SLO:把可靠性变成数学 — SLI/SLO/SLA 语义、error budget、burn rate 告警、可靠性目标设计 核心问题:月度 99.9% 可用性换算成多少分钟的 error budget?当 burn rate 超过 1 时,意味着什么? 关联:→ 02-指标:时间序列的量化哲学(SLO 建立在指标之上)→ 04-可观测性:从已知失败到任意提问(SLO 定义”正常”,可观测性用于理解”异常原因”)
演进:统一仪器语言
核心问题:OpenTelemetry 解决的是”仪器化”问题还是”后端”问题?Collector 在 OTel 架构里的作用是什么?OTLP 协议相比 Prometheus scrape 有什么本质差异? 读完之后:理解 OTel 的四层架构(API / SDK / Collector / Exporter),理解 Collector 作为可观测性管道的作用,理解 Exemplar 如何连接指标和追踪,理解 OTel 在仪器化锁定问题上的战略意义。
- 07-OpenTelemetry:三个信号的统一语言 — OTel API/SDK/Collector、OTLP、auto-instrumentation、Exemplar 核心问题:用 OTel SDK 仪器化一个服务之后,数据是如何流向 Prometheus、Jaeger、Loki 三个不同后端的?Collector 在中间做了什么? 关联:→ 02-指标:时间序列的量化哲学(OTel metrics 和 Prometheus 的兼容层)→ 05-分布式追踪:因果链的精确重建(OTel traces 是追踪的事实标准)→ 03-日志:结构化事件的叙事力量(OTel logs 规范)→ 云原生与平台工程 MOC(eBPF 和 OTel 的协同)
演进:零侵入洞察
核心问题:持续分析(Continuous Profiling)和追踪、指标的区别是什么?eBPF 如何在不修改应用的情况下采集 CPU 火焰图?Parca 和 Pyroscope 的存储模型有什么差异? 读完之后:理解 on-CPU / off-CPU profiling 的区别,理解 eBPF perf event 采样的工作原理,理解持续分析如何定位”监控发现异常但追踪找不到原因”的盲区。
- 08-持续分析:eBPF 的零侵入内核洞察 — continuous profiling、on/off-CPU 分析、火焰图、Parca/Pyroscope 核心问题:追踪显示某个服务的 P99 升高了,但每一跳的 span 耗时都没有明显异常——这种情况下,持续分析能找到什么追踪找不到的信息? 关联:→ 云原生与平台工程 MOC(eBPF 是本篇的底层机制,深入见平台工程 06 篇)→ Linux 系统 MOC(perf 和 eBPF 的内核基础)→ 05-分布式追踪:因果链的精确重建(两类信号互补,覆盖不同盲区)
五、按场景的阅读路径
路径一:第一次学可观测性
从经典到现代,建立完整的历史感:
01(监控:理解经典范式的逻辑)
→ 02(指标:量化系统行为)
→ 03(日志:结构化事件)
→ 04(可观测性:范式转变)
→ 05(追踪:分布式系统的新工具)
→ 06(SLO:可靠性的数学化)路径二:运维 / SRE 工程师
关注告警、指标和 SLO:
02(指标和告警:日常运维基础)
→ 06(SLO:把告警从阈值升级到症状)
→ 03(日志:故障排查的叙事工具)
→ 04(可观测性:理解为什么监控不够)
→ 05(追踪:分布式系统排查的核武器)路径三:后端开发者(理解系统行为)
关注仪器化和如何理解自己的服务:
02(指标:如何给自己的服务定义 RED 指标)
→ 03(日志:如何设计结构化日志)
→ 05(追踪:如何理解跨服务调用)
→ 07(OTel:一次仪器化,后端自由选择)
→ 06(SLO:如何定义服务的可靠性目标)路径四:关注新技术方向
关注可观测性的演进前沿:
04(可观测性哲学:理解为什么)
→ 07(OpenTelemetry:信号统一标准)
→ 08(持续分析:eBPF 零侵入)
→ 05(追踪:与持续分析互补)路径五:正在选型(Prometheus 还是 OTel?ELK 还是 Loki?)
01(监控:经典方案的优劣,Nagios/Zabbix 的适用场景)
→ 02(指标:Prometheus 生态的完整形态)
→ 03(日志:ELK vs Loki 的存储哲学差异)
→ 07(OTel:为什么 OTel 是长期正确的仪器化选择)
→ 04(可观测性:你的系统规模是否真的需要可观测性)六、延伸方向
这个系列聚焦于可观测性技术的理解与使用。以下方向与本系列相关,但各自构成独立的学习领域:
-
可靠性工程实践(SRE):On-call 设计、事故管理、复盘(postmortem)文化、混沌工程——这些是组织级别的工程实践,超出本系列的技术边界,见 Google SRE Book 和 SRE Workbook。
-
云原生可观测性基础设施:Kubernetes 上的 Prometheus Operator 部署、Grafana Stack(Loki + Tempo + Mimir)、OTel Operator——这些是平台工程的职责,见 云原生与平台工程 MOC。
-
eBPF 深入:本系列第 08 篇介绍持续分析的使用,eBPF 的内核机制和 Cilium/Tetragon 的完整架构见 云原生与平台工程 MOC 第 06 篇。
-
Linux 系统工具基础:perf、ftrace、strace 的内核原理,eBPF 建立的 Linux 基础,见 Linux 系统 MOC。
-
架构质量属性:SLO 是架构设计的可靠性约束,架构决策(微服务拆分粒度、事件驱动边界)直接影响可观测性代价,见 软件工程与架构 MOC。
-
安全可观测性:安全事件检测、异常行为分析(SIEM)是安全与可观测性的交叉地带,见 安全工程 MOC。
-
AIOps 与智能告警:基于 ML 的异常检测、根因分析自动化——目前工程成熟度参差不齐,尚不适合作为系统性知识体系建立。