监控系统会死在哪里

仪表盘一片绿色,用户已经宕机了。你遇到的不是可观测性问题,是控制系统故障。

这篇文章来自一次真实事故的复盘。不是监控入门,是设计审查:为什么生产组织在最需要可见性的时候反而看不见。

那次凌晨两点的事故

现场

凌晨 02:17,客户支持群冒出第一条消息:某大客户请求大量超时。

02:19,Oncall 被拉醒。

02:21,打开 Grafana,一片绿色。CPU 正常,Memory 正常,Error rate 接近 0。系统看上去啥事没有。

02:25,更多客户报告超时。业务负责人进会议,开始问:影响多少客户?范围多大?要不要回滚?多久能恢复?

没人能答上来。

监控系统在那里。但它没给出任何能拿来做决策的信息。

那一刻我意识到:监控没坏,但已经失效了。

四层崩塌

第一层:监控看到的和用户感知到的不是一回事

02:30,初步排查。Infra dashboard 显示 CPU < 40%,Memory 正常,Network 正常,Pod 数量正常,没有明显 error spike。但用户那边:请求超时,页面卡死,API latency 超过 20 秒。

第二层:最关键的问题答不上来

管理层问了五个问题:影响面多大?是某个 region 吗?是单个客户吗?要不要 rollback?要不要对外公告?一个都答不了。

监控存在,但没有决策能力。

第三层:信任开始崩塌

02:40,工程师开始 SSH 进机器,手动翻日志,临时加 debug,打印内部状态。逐渐没人看 dashboard 了。

监控一旦被绕过,它就失去了控制权。

第四层:监控系统自己也要撑不住了

02:50,Prometheus 查询变慢,高 cardinality 查询直接 OOM,有些 dashboard 加载超过 40 秒。

那时候真正的恐惧出现了:如果 Prometheus 挂了,我们就彻底瞎了。

最终定位

03:12,手动排查发现:某核心依赖服务连接池耗尽,导致级联超时。

但 infra metrics 没触发 alert,没有 dependency latency SLO,没有 per-client SLO,没有 request saturation 指标。

监控没有错。只是没有监控到真正的风险。

事后来看,这不是监控缺失的事故,是监控系统设计暴露的事故。Dashboard 在,Alert 在,但系统处于"盲飞"状态。我们有可观测性,但没有控制能力。

于是我开始想一个问题:如果一个监控系统会死,它会死在哪里?


90% 的监控系统没有价值

02:25,管理层问"有多少用户受影响"的时候,仪表盘答不了。它显示了 CPU、内存、网络,基础设施工程师关心的一切。但它回答不了真正重要的问题。

多数监控系统测量的东西是错的。它们测量基础设施,不测量组织行动能力。

监控的价值不在数据本身,在于能不能影响行为和决策。不能触发行动的信号就是噪音。

02:25 那个时刻,我们有数据:CPU 正常,内存正常,错误率很低。但我们无法决定:该回滚吗?多少用户受影响?爆炸半径多大?

监控价值 = 改变行为或决策的能力。 其他都是次要的。

CPU 90% 不一定是风险

思想实验:CPU 90%,有风险吗?

CPU 90% 但没有用户影响,可能没问题。CPU 90% 但用户超时,有问题。CPU 90% 在流量高峰时,预期之内。CPU 90% 在低流量时,可疑。

原始指标告诉你状态,不告诉你风险。风险需要解释。我们事故中,CPU 正常,但用户宕了。指标没错,它只是没测对东西。

信号和噪音

02:25,我们的基础设施指标太多(噪音),用户影响信号太少。信噪比是倒的。

收集一切、对一切告警,最终没人看。解法不是更多数据,是更少噪音:主动过滤、分组、提高置信度阈值、移除低价值指标。

决策延迟

衡量行动能力的核心指标是决策延迟:从信号到行动决策的时间。

那次事故,决策延迟是无穷大。信号有(CPU、内存),但做不了决策(回滚?扩容?等?)。

好的监控系统缩短决策延迟。目标:关键事故 5 分钟内走完信号检测(< 1 分钟)、解释(< 2 分钟)、决策(< 2 分钟)。我们卡在解释阶段,不知道信号对用户意味着什么。

多数监控系统回答的问题就是错的。它们回答"系统状态是什么",应该回答"我们该做什么"。


监控系统是安全系统

02:25,我们答不了"安全吗?要回滚吗?"

监控系统是安全系统。目的是风险检测和决策支持,不是指标收集。

飞机驾驶舱的思路

飞机驾驶舱不给你看原始高度、燃料、速度。它显示的是"距离危险阈值"、“燃料够不够到目的地”、“接近失速速度”。

原始指标不如处理后的洞察有价值。监控不是显示高度,是保证你不会坠毁。

02:25,我们有原始指标(CPU、内存),没有安全信号(用户安全吗?风险在扩大吗?)。

控制循环

监控是反馈控制系统,不是被动观察。

控制循环:现实 → 信号 → 解释 → 风险框架 → 决策 → 行动 → 系统变化 → 新现实。任何一环断了,监控就变成观察噪音。

graph LR A[现实<br/>User Reality] --> B[信号<br/>Signal] B --> C[解释<br/>Interpretation] C --> D[风险框架<br/>Risk Framework] D --> E[决策<br/>Decision] E --> F[行动<br/>Action] F --> G[系统变化<br/>System Change] G --> A style B fill:#ffcccc style C fill:#ffcccc style D fill:#ffcccc style E fill:#ffcccc B -.断裂点1: 基础设施信号<br/>非用户信号.-> B C -.断裂点2: 无法解释<br/>信号含义.-> C D -.断裂点3: 无SLO/错误预算<br/>无风险评估.-> D E -.断裂点4: 无法决定<br/>做什么.-> E

那次事故里,循环在多个点断裂:信号是基础设施的不是用户的,解释做不了,没有 SLO 和错误预算做风险评估,做不了决策,没触发行动。

控制循环从未闭合。

控制理论视角

振荡:告警风暴,告警触发行动,行动导致更多告警,反馈放大。那晚没遇到,以前见过,一旦开始很难停。

噪音:误报。工程师静音,真告警也被静音。那晚情况相反,基础设施正常,用户宕了。噪音掩盖了信号。

延迟:数据滞后。那晚数据是新鲜的,但数据本身就是错的:CPU 新鲜,用户影响缺失。正确信号的延迟才致命。

监控系统必须能回答:安全吗?在变糟吗?需要行动吗?什么行动?答不了这些,它就不是安全系统,只是数据显示器。


让监控系统比生产更稳定

02:50,Prometheus 查询 OOM,高基数查询崩溃,仪表盘加载 40 秒以上。Prometheus 再挂一下我们就彻底瞎了。

跟生产一起死的监控系统没有用。

监控系统是关键基础设施,必须比它监控的东西更稳定。我们特别需要在生产出问题的时候做监控。如果监控自己不稳定,最需要视力的时候就瞎了。

生存能力层级

层级 架构特征 应用崩溃时 AZ失败时 区域失败时 适用场景
0 与应用共享基础设施 监控崩溃 监控崩溃 监控崩溃 开发环境
1 独立VM/存储 监控存活 监控失败 监控失败 小型生产
2 独立故障域(不同AZ) 监控存活 监控存活 监控失败 关键生产
3 跨区域冗余+缓冲 监控存活 监控存活 监控存活 关键业务

那次事故里我们大概在层级 0 到 1 之间。生产出问题的时候,监控也跟着晃。Prometheus 挣扎,查询变慢,距离彻底失明只差一次崩溃。事故之后组织才投资做了独立部署。

基数问题

02:50 Prometheus 查询 OOM 的原因是基数爆炸。标签相乘:service x region x instance x endpoint x status = 数百万时间序列。稳态下能跑的查询,事故期间崩了。

解法不是"换更好的数据库",是标签治理:限制标签维度、用记录规则、早期聚合。

元监控

得监控监控系统。但元监控必须比主监控更简单,否则就是递归。

需要盯的:监控系统可用性、数据收集成功率、查询性能、存储健康。那次事故里,Prometheus 开始挣扎的时候我们不知道,直到查询失败才发现。元监控可以提前检测到退化。


可观测性存储是数据平台问题

02:50 Prometheus 查询 OOM、仪表盘加载 40 秒以上,根源是可观测性存储是个数据平台问题,不是可视化问题。

多数人以为监控 = Grafana 仪表盘。Grafana 只是可视化层,核心是数据库。查询挂了仪表盘就挂了,数据库挣扎一切都挣扎。

可观测性存储是高频时间序列数据仓库:写重、读重、高基数、压缩、保留、成本压力。这不是 OLTP 数据库的问题。

基数爆炸的解法上面说过了。存储分层也重要:热事故需要热数据、快速查询,不应该在热事故期间查冷数据。那次事故我们没做冷热分离,也没做预计算和缓存,所有查询都实时算,事故期间先变慢再失败再 OOM。


从 CPU 到收入:监控层级要跃迁

CPU 正常,客户宕了。为什么看不到用户影响?因为监控在错误的层级。监控的是基础设施,该监控的是业务价值。

监控有层级:业务风险/价值 → 模型/逻辑 → 管道 → 服务 → 基础设施。越接近业务越接近真相,越接近基础设施越接近噪音。

那次事故里我们卡在基础设施层级。CPU、内存都正常,看起来没事,但用户已经宕了。真相在业务层级,我们看不到。

这不是缺数据的问题,是数据在错误层级的问题。

graph TD A[业务风险/价值层<br/>用户影响、收入、SLO] -->|更接近真相| B[模型/逻辑层<br/>业务逻辑、数据流] B --> C[管道层<br/>请求流、依赖链] C --> D[服务层<br/>服务健康、延迟] D -->|更接近噪音| E[基础设施层<br/>CPU、内存、网络] F[02:25事故] -.监控位置.-> E F -.真相位置.-> A style A fill:#90EE90 style E fill:#FFB6C1 style F fill:#FFD700

基础设施指标不是没用,但没有上下文化就是噪音。CPU 90% 不代表风险,CPU 90% 加上用户影响才是风险。

认知栈

从原始信号到行动有一条完整链条:原始信号 → 处理后的信号 → 风险解释 → 决策接口 → 行动。

层级 02:25 事故状态 缺失后果
原始信号(CPU、内存) 存在 -
处理后的信号(聚合、趋势) 存在 -
风险解释(SLO、错误预算) 缺失 不知道信号对用户意味着什么
决策接口(回答关键问题) 缺失 答不了"影响多大?要回滚吗?"
行动(告警、自动化响应) 缺失 触发不了回滚、扩容

栈在风险解释处断了,后面全跟着断。

管理层问"是单个客户吗?“答不了,因为没有每客户 SLO。有的话就能看到"客户 X 宕了,其他正常"或者"所有客户都受影响”。

要监控价值流(用户请求 → 服务 → 依赖 → 响应 → 用户体验),不是监控基础设施(CPU、内存、网络、Pod)。那次事故,价值流断在连接池耗尽那里,我们看不到。


仪表盘要支持决策,不是展示指标

如果 02:25 有一个支持决策的仪表盘,它会显示:用户影响、风险级别、推荐行动。不是 CPU、内存、错误率。

仪表盘必须能回答四个问题:系统安全吗?在变糟吗?需要行动吗?什么行动?回答不了就没有价值。

战术监控(核心):实时、绑定行动、聚焦决策。比如 Oncall 仪表盘、告警系统、SLO 监控器。

探索监控(次要):历史、分析、洞察。比如容量规划、趋势分析、事后分析工具。

核心监控必须是战术的。那次事故里我们需要战术监控,手上有的是探索型的(历史趋势、容量规划),类型错了。

仪表盘价值的核心衡量指标是决策延迟:从打开仪表盘到做出决策的时间。02:25,决策延迟无穷大,打开了仪表盘,看到了指标,但什么都决定不了。

如果当时有用户影响数据,我们能决定现在回滚还是等。有风险级别,我们能评估紧迫性。有推荐行动,我们能行动。有爆炸半径,我们能确定事故范围。

仪表盘要为事故条件设计,不是为稳定状态。事故时需要快速决策、清晰行动、风险评估。稳定状态的需求(容量规划、趋势分析、优化)是次要的。


为什么工程师绕过仪表盘

02:40,工程师开始 SSH 进机器,彻底绕过仪表盘。因为仪表盘帮不上忙:看到指标,支撑不了决策,只好自己找路。

信任崩塌

监控系统是信任系统。信任崩塌的症状:误报太频繁、出过漏报(错过真实事故)、数据延迟、仪表盘和真实体验对不上、事故时数据缺失。

那次事故里好几条都中了:仪表盘绿色但用户宕了、没有用户影响数据、错过了真正的问题。信任一旦崩塌,工程师就绕过监控,自己 SSH、翻日志。监控变成摆设。

信任要靠工程手段维护

信任预算:为每个信任组件分配错误预算(误报、漏报、延迟)。信任透明:显示数据新鲜度、置信度分数、错误率。信任恢复:承认误报,修根本原因,沟通改进。信任监控:盯静音率、绕过率。

那次事故里这些都没有。信任无声地崩塌了。

所有权

没有所有者 = 不存在。仪表盘在那里,但没人拥有,所以没人维护,没人信任,自然衰败。所有权模型可以是单一所有者、轮换、共享,甚至社区维护,但必须明确结构,绝对不能模糊。

工程师绕过监控有四种原因:不帮忙(答不了问题)、不可靠(误报、数据缺失)、太慢(加载太久)、门槛太高(只有资深工程师能解读)。那次事故里四条都中了。


从风险出发设计监控

如果按风险设计,我们会监控连接池饱和度。但我们没有。我们监控 CPU、内存、错误率,没有监控连接池饱和度、依赖延迟、请求饱和度。

为什么?因为 CPU 容易、内存容易、错误率容易。连接池饱和度要先想清楚风险。

正确的思路是:先识别什么可能出错(连接池耗尽、依赖超时、请求饱和),再确定什么信号能表征这些风险(连接池利用率、依赖延迟、请求队列深度),再做优先级排序(连接池耗尽导致级联超时,高影响高概率,池利用率 > 80% 告警),最后验证(能检测吗?告警触发正确行动吗?信号可靠吗?)。

我们跳过了这些,监控容易的,没监控重要的。如果当时从风险出发设计,在用户注意到之前就能发现问题。

监控必须能回答:在赚钱吗?在伤害用户吗?失控了吗?在变慢吗?快出问题了吗?答不了这些就没有存在价值。

六种死法

死亡模式 症状 根本原因 事故中是否出现
存在但不被信任 工程师绕过、SSH 手动排查 信任崩塌、无所有权
告警噪音崩塌 告警风暴、误报过多、被静音 无信号过滤、无分组节流
系统脆弱 Prometheus OOM、查询变慢 与应用耦合、无元监控
答不了决策问题 有指标但做不了决策 只有原始指标、无风险框架
跟生产一起死 生产崩溃时监控也崩溃 共享基础设施 接近
监控和现实对不上 绿色但用户宕了 快乐路径偏见、错误 SLO

那次事故里,多种死亡模式同时出现。但追溯到根上都是同一个问题:监控不是为"不确定性下的组织决策能力"设计的。


它会死在哪里

回到最初的问题。

现实 → 原始信号 → 聚合信号 → 风险解释 → 决策层 → 行动 → 系统变化 → 反馈。链条任何一环断了,监控就失效。

那次事故里,链条在多处断裂:风险解释缺失、决策层缺失、行动缺失。有信号有聚合,但没有解释、没有决策、没有行动。

信任崩塌导致工程师绕过,监控变摆设。生存能力不足导致监控跟着生产一起摇晃。风险驱动设计缺失导致监控了错误的东西。决策能力缺失导致什么都决定不了。控制循环断裂导致没有反馈、没有纠正。一环断,环环断。

监控系统的唯一目的是在不确定性中维持组织行动能力。 不是数据可见性,不是调试,不是指标收集。

我现在做监控设计的时候,第一个问题永远是"这个信号能帮谁做什么决策"。能回答的留下,回答不了的砍掉。从那次事故之后,再也没让仪表盘骗过我。