“幸福的家庭都是相似的,不幸的家庭却各有各的不幸”,托尔斯泰的名言。在 BUG 定位这件事情上,其实也有类似的现象:”菜鸟们的紧张无措都是相似的,老鸟们的方法却各有各的不同”。
年年过大促,年年定位现网故障。果不其然,今年 9.9 大促再次踩坑。看到组内的新手们排查问题的手足无措,也就有了这篇文档。本文的目的不在于穷举所有排查问题的手段,而在于帮助新手们避雷。
蜻蜓点水
当遇到无法轻易复现,并且缺少有用的日志辅助缺陷排查的时候,新手们的一般会选择去看代码。然而,最关键的点来了,他们并不是在真正看代码,他们只是印证自己”脑海中记忆的代码” 跟代码库里的是一致的。最常见的一个结果,就是得到一个 “代码是这样的呀、没有问题呀” 的结论。看代码过程是轻浮的,是跳跃的。
然而,计算机执行的并不是你脑海中的代码,而是实实在在的代码。计算机是严谨的、会一丝不苟的,从调用入口开始,一行不漏的逐行执行完毕,然后返回结果。任何细微的差异都有可能执行的是路径完全不同,而 BUG 就是因为走了跟预期不一样的执行路径。
看代码需要一行一行的看,一层层调用的展开。无论是自己编写的代码,还是开源仓库的代码,还是服务框架的代码,任何一行代码都不应该被跳过。
脚踏实地,而不是蜻蜓点水。
轻视数据
大型复杂的系统产生了繁多的数据。不同的团队成员看到数据(事实)之后,会加入自己对数据的判断(观点),呈现出二次加工之后的数据。最终可能得到是一份夹杂了观点和事实的数据。
当你听到蹄子声响时,你可以说听到了马蹄声,但实际上也可能是斑马蹄的声音,虽然概率很低。
同时,就会出现以下类型的数据误用:
- 不对数据数据进行汇总、分析,基于片面的数据进行假设
- 基于不可靠的数据,导致错误的假设
基于错误的、片面的数据,进行假设,最终大概率是徒劳而无功。
靠谱的使用数据的方式,应当是团队成员把相关的数据汇聚,根据业务架构形成 “马赛克调查墙”,基于 “马赛克调查墙” 确定方向,再进行假设。
轻视逻辑
很多很多人一上来就开始猜答案,基于他们认定的答案来提问,这是特别坏的一个习惯,因为这样找问题几乎就只能凭运气了。
“分治”(Divide & Conquer)是一种非常通用的解决方案。在一个多层系统中,整套系统需要多层组件共同协作完成。最好的办法通常是从系统的一端开始,逐个检查每一个组件,直到系统最底层。这样的策略非常适用于数据处理流水线。在大型系统中,逐个检查可能太慢了,可以采用对分法(bisection)将系统分为两部分,确认问题所在再重复进行。逐项排除、层层递进,才能系统的剥离出真相。
还有一个常见的逻辑误区“相关性 = 因果性”。然而,相关性并不代表因果性。比如:
统计表明,游泳死亡人数越高,冰糕卖得越多,也就是游泳死亡人数和冰糕售出量之间呈正相关性,我们可以由此得出结论说吃冰糕就会增加游泳死亡风险吗?显然不可以!这两个事件显然都仅仅是夏天到了气温升高了所导致的,吃不吃冰糕跟游泳死亡风险根本没有任何因果关系。
同理,跟 BUG 相关的异常数据,不代表数据的操作导致了 BUG。为了论证因果关系,需要更加严密的实证来说明。按照相关理论复现所有 BUG 表现的特性,且只表现这些特征。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。