凌晨两点十五分,告警群炸了。

生产环境某个服务开始 OOM(Out of Memory),Pod 反复重启,LBs 在背后疯狂重试。我睡眼惺忪打开电脑,第一反应是看监控——CPU 正常、QPS 正常、错误率正常。所有指标都"绿"着,除了 JVM 堆内存那一条红线,笔直地撞到了天花板。

但更让我后背发凉的是另一件事:我从监控里看不出任何"为什么"。只知道内存涨了,不知道是哪段代码在分配;只知道 Pod 重启了,不知道是哪次请求触发的;只知道服务挂了,不知道这个故障影响到了哪些下游。

那一刻我才真正理解了一句话——可观测性不是"出了问题能看",是"出了问题能问"。

我以前理解的"可观测性"是错的

在 OOM 之前,我以为我懂可观测性。我有 Prometheus 在采指标,有 Loki 在收日志,有 Grafana 在画图。仪表盘做得漂漂亮亮的,红黄绿三色一眼扫过去感觉一切尽在掌握。

但 OOM 那个晚上我发现:我有的是"看",缺的是"问"。

指标告诉我"发生了什么"——比如内存到了 95%。但它不告诉我"为什么"——是哪个线程在分配?是哪段代码路径在触发?是哪个用户的请求造成的?

日志告诉我"细节"——但我面对的是几百个 Pod 同时在打日志,我要找的是某一次具体的失败调用,单条日志看再多也连不成线。

没有链路追踪,我就没法把"这一秒的内存峰值"和"那一次的某次具体请求"连起来。可观测性的三大支柱——日志、指标、链路——少了任何一根,另外两根就只是数字。

三个真实的问题

那次 OOM 之后我开始系统性补课,问了自己三个问题:

第一:我能在 5 分钟内回答"现在线上正在发生什么"吗?

以前我的答案是"看仪表盘"。但仪表盘只能回答"过去 5 分钟发生了什么"。可观测性需要回答的是"现在正在发生"——也就是当下此刻。当告警触发,工程师需要的不只是历史数据,还需要"问题现场"。这要求数据延迟低、查询灵活、维度可下钻。

第二:我的告警是"症状"还是"病因"?

以前我设的告警全是症状——"内存高于 90%"、"错误率高于 5%"、"响应时间超过 1 秒"。这些是身体不舒服时的"发烧"、"咳嗽"。但 OOM 让我意识到,我连"为什么会发烧"都答不上来。

好的告警应该尽量接近病因——不是"内存高了",而是"短时间内有大量对象被分配且未释放"。不是"错误率高了",而是"某个用户的某个操作触发了 NPE"。后者难设,但能真正减少 MTTR(平均修复时间)。

第三:我能"问"问题吗?

这是我最被忽视的一点。可观测性真正的力量不在"看到"——仪表盘能看到。在于"问"——当我想知道"过去一小时内 P99 响应时间超过 500ms 的请求都长什么样",我能不能用一句类似 SQL 的话把它查出来?

如果答案是"不能,要去翻日志",那这个系统不是可观测的,是可"监"不可"问"的。

我现在的三件套

那次 OOM 之后我把可观测性栈重做了一遍。不是堆最贵最全的工具,是按"能不能问"来选。我的当前三件套——

指标层:Prometheus + Grafana。 不变。指标层的核心是"先聚合再存储",适合回答"过去 X 分钟的整体趋势"。我把所有服务的关键 SLI(请求量、错误率、延迟、饱和度)都接了进去,做成一张全局仪表盘,一眼能看所有服务的健康度。

日志层:Loki + 标签约定。 关键不是 Loki 本身,是"打日志的标签约定"。我让所有服务在结构化日志里强制带 trace_id、span_id、user_id、route 四个标签。这样日志能跟链路串起来,能按用户切片,能按接口分组。日志不再是"一坨字符串",成了"可以查的数据"。

链路层:OpenTelemetry + Tempo(或 Jaeger)。 选 OTel 不选 Zipkin 那一套,是因为它是 CNCF 标准,不会被任何一家绑定。Trace 覆盖所有 HTTP 调用、消息消费、数据库访问、Redis 调用——任何超过 50ms 的操作都有 Span。OOM 的根因是某段 SQL 没走索引扫了 100 万行——这种问题在日志里找一个月都找不到,在 Trace 里一秒就能定位。

三个组件不是孤岛,是连在一起的:指标异常 → 日志按 trace_id 查 → Trace 拉出完整调用链 → 直接定位代码行。这就是"可观测"的真意。

可观测性是工作流问题,不是技术选型问题

最后说一句可能冒犯的话:大多数团队的可观测性问题,不是工具问题,是工作流问题。

工具再好,没有人去用——告警没人在意,仪表盘没人看,Trace 没人查——那这个系统的可观测性就是零。我见过有的团队花一百万买了一套顶级 APM,结果出问题时所有人还是去翻日志。

真正让可观测性生效的不是工具,是习惯:告警不是给"系统"的,是给"工程师"的,必须有响应。Dashboard 不是给"领导"的,是给"值班人"的,必须能指导操作。Trace 不是给"事后复盘"的,是给"正在救火的人"的,必须能 5 分钟内查到根因。

这三条做不到,再贵的工具也是摆设。

还没想明白的事

有一个边界我一直没想清楚:可观测性的成本,应该在开发期就规划,还是运维期再补?

前者的好处是"从一开始就有",坏处是开发节奏被拖慢、很多指标后面发现没用上。后者的好处是"按需建设",坏处是出问题时已经晚了——补可观测性至少要一周,而生产故障可能 1 小时就要恢复。

我现在倾向于"在架构设计阶段把可观测性作为非功能需求写进 ADR,但不一定要立刻实现,里程碑里排上"。但这中间的分寸,每个项目可能不一样。如果你们团队有更聪明的做法,欢迎告诉我。