监控系统会死在哪里
仪表盘一片绿色,用户已经宕机了。你遇到的不是可观测性问题,是控制系统故障。
这篇文章来自一次真实事故的复盘。不是监控入门,是设计审查:为什么生产组织在最需要可见性的时候反而看不见。
那次凌晨两点的事故
现场
凌晨 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、内存),没有安全信号(用户安全吗?风险在扩大吗?)。
控制循环
监控是反馈控制系统,不是被动观察。
控制循环:现实 → 信号 → 解释 → 风险框架 → 决策 → 行动 → 系统变化 → 新现实。任何一环断了,监控就变成观察噪音。
那次事故里,循环在多个点断裂:信号是基础设施的不是用户的,解释做不了,没有 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、内存都正常,看起来没事,但用户已经宕了。真相在业务层级,我们看不到。
这不是缺数据的问题,是数据在错误层级的问题。
基础设施指标不是没用,但没有上下文化就是噪音。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 | 是 |
那次事故里,多种死亡模式同时出现。但追溯到根上都是同一个问题:监控不是为"不确定性下的组织决策能力"设计的。
它会死在哪里
回到最初的问题。
现实 → 原始信号 → 聚合信号 → 风险解释 → 决策层 → 行动 → 系统变化 → 反馈。链条任何一环断了,监控就失效。
那次事故里,链条在多处断裂:风险解释缺失、决策层缺失、行动缺失。有信号有聚合,但没有解释、没有决策、没有行动。
信任崩塌导致工程师绕过,监控变摆设。生存能力不足导致监控跟着生产一起摇晃。风险驱动设计缺失导致监控了错误的东西。决策能力缺失导致什么都决定不了。控制循环断裂导致没有反馈、没有纠正。一环断,环环断。
监控系统的唯一目的是在不确定性中维持组织行动能力。 不是数据可见性,不是调试,不是指标收集。
我现在做监控设计的时候,第一个问题永远是"这个信号能帮谁做什么决策"。能回答的留下,回答不了的砍掉。从那次事故之后,再也没让仪表盘骗过我。