在讨论这个问题之前。先分享一个信息层级的概念。说:信息分4个层级,最底下是数据,杂乱无章,比如海量的指标、日志、链路追踪的数据;数据上面是特征,比如最大值、最小值、同环比等,比如5个服务实例,延迟的最大的是哪个,这叫数据特征;特征上面是观点,从故障定位场景来举例,比如根据特征数据分析之后发现,数据库没有问题,依赖的第三方服务也没问题,这就是观点;观点之上就是洞察,或称洞见,综合所有观点,得出故障定位结论,得知具体是哪个模块的什么原因导致了本次故障,就是最终洞察。画个图示例一下:
要想得到最终的洞察(定位到故障),首先要依赖底层的数据完备性,否则就是巧妇难为无米之炊!但是故障原因五花八门,数据能全么?做过 SRE 或者运维的朋友肯定感触颇深,故障可能是电源模块坏了、机房空调坏了、机柜压住网线了、供电不稳、某个盘故障了、中间件配置错了、被黑客攻击了、分布式中间件脑裂了、写日志hang住了、程序配置错了、程序连接第三方的地址错配成线下地址了、DNS配错了、证书过期了、代码Bug了、疏漏了某个罕见用户流程…等等等等。
这么多可能的故障原因,要通过可观测性数据分析出来,这数据能全么?比如代码 Bug,要想能根据可观测性数据分析出是哪一行代码的问题,岂不是要像在 IDE 里调试那样,每一行代码的输入输出都得拿到啊,这成本谁扛得住啊,性能损耗谁扛得住啊…
如果我们的目标只是定位直接原因,找到止损依据尽快止损,这个底层数据需求就少多了。比如我们不需要知道是哪行代码出了问题,我们只要知道是某个模块做了变更导致了故障,就可以去止损(这个场景的止损动作就是回滚)了。再比如,多活的服务,有时仅仅知道是 A 机房的问题就可以了,把流量切到 B 机房就可以解决。
综上,个人观点:使用可观测性数据定位根因,几无可能100%覆盖全部场景!因为数据就不可能全!但如果只是用可观测性数据定位直接原因,找到止损依据,则100%是可以做到的,而这,才是我们应该努力的方向。
当 SRE 在谈论故障定位的时候,其实谈论的时是如何找到直接原因,尽快止损。而根因,可以留在复盘阶段慢慢找的。
如何找到故障的直接原因
回答这个问题之前,我们先来看看一个服务要想正常运行,依赖了哪些内容,或者说一个服务如果出故障,可能会是哪里的问题。如果我们能够枚举故障类别,那么我们就可以针对每个类别去分析,找到故障的直接原因。
首先,依赖的基础设施(基础网络、硬件、Runtime环境)不能出问题,依赖的第三方其他服务不能出问题,这两个方面大家比较容易理解,不多说了。还有就是服务本身的变更,比如二进制变更、配置的变更、部署方式的变更、流量接入方式的变更,等等,也可能引发问题。最后就是上游访问的方式,比如流量突增,显然也可能会带来故障。
那针对这些故障场景,我们应该去看哪些数据呢?这其实就是可观测性数据底座的建设方向。
咦?说来说去,还是要建立 metrics、logs、traces、events?是的,但不仅是,只有数据还远远不够,我们需要通过平台工具,通过数据运营整理,帮助用户找到数据特征,建立初步观点,最终形成洞察定位故障直接原因。还记得那张信息层级的图吧:
网上有人批评可观测性三支柱的说法,核心要点是:不能只关注 raw data,就像一道菜,只有原料还不能称之为一道菜,没有炊具、菜谱、厨师,无法最终产出那道菜(客人要的是那道菜,那道菜才是结果,应该没有哪个餐厅说,你看我原料都有,完活了,让客人吃吧,应该没有这样的餐厅…)。
Martin Mao 曾经也写过一篇文章《Beyond the 3 Pillars of Observability》来论述这个事情。
他的核心观点是:只关注三支柱raw data,认为有了三支柱数据就建立了可观测性,是不对的,我们更应该面向结果来思考如何构建整个体系,Martin Mao 认为,所谓的结果,就是 Remediate,就是止损!英雄所见略同。
可观测性体系具体要如何做才能辅助技术团队止损
还是参考刚才信息层级的图,有了 raw data 数据底座之后,可观测性体系还需要利用平台能力、通过数据运营整理,呈现数据特征、帮用户建立初步观点,最终形成洞察,定位故障直接原因。
可观测性体系要告诉我故障模块
当然,还有其他观点可以输出,比如是否是容量不足导致的故障,大家可以自行思考看看还可以让可观测体系输出哪些观点。但是,罗马不是一天建成的,在某个阶段,可观测性体系输出的观点有限,不足以帮我们定位故障,此时,可观测性体系还可以做什么呢?
至少,还需要提供工具帮我们分析数据特征,别让用户陷入海量散乱的可观测性 raw data 中。这需要多维分析引导能力、数据串联打通能力。举一个数据串联的例子:
总结