本以为线上问题就已经够棘手了,没曾想,线上的偶现问题才是最要命的
好些日子没写文章了,今天不扯代码,讲点没有多少营养的心得体会
一、真正难解的问题
作为最接近用户的前端,每每出现问题当然首当其冲,如果必现也就罢了,Debug 或者 抓包什么的反正各种手段,是自己的问题解决问题,不是自己的问题,也方便甩锅出去。但是如果这个项目恰好还复杂度高、链路长、关联方很多,并且这个问题还是 偶现 的 线上 问题,无异于在开动的火车上排查轨道上出现的大石头,却还不知道大石头会在哪出现,你说绝望不绝望
遇到这样的问题该怎么做呢?当然不是放弃啦
二、如何应对
尝试寻找复现路径
虽虽然是一个偶现的问题,如果复现的概率比较高,尝试在这些复现的现象当中寻找一些内在的关联,例如 弱网、快速重复点击、超时操作等等,需要一些经验以及运气。如果有幸找到了必现路径,那么恭喜啊,这个问题从一个 偶现 的问题降级到了一个 必现 问题的 Level。这个时候应该怎么做还需要我教你!!?
分析代码可能的问题,逆推必现路径
上面第一步,可以让测试的同学帮忙操作,而你呢,可以把精力放在分析你的代码上,考虑各种场景,是不是会有漏洞,是不是会导致问题,然后再来逆推必现路径。如果某个逆推出来的路径刚好可以复现这个问题。那么,拍完大腿动动手指把问题解决,你就可以好好去享受你的下午茶了
完善监控日志
糟糕,除了客户线上反馈了这个问题(视频截图为证,抵赖不得),整个项目组没有谁能复现这个问题,或者就算测试的同学给偶然复现了,也根本来不及让你 debug 捕捉日志。你在分析代码上也发现不了蛛丝马迹,这个时候就要依赖于日志系统了。在你觉得必要的地方,打印日志上传日志系统,毕竟以线上用户的量级,就算发生的概率只有千百分之一,也很容易收集到一些关键的信息
带了日志的版本发出去一段时间之后,是时候分析日志了,某个接口报错了?某个 native 的 js api 没有返回?还是后天返回的某个数据类型跟预期的不一致?Anyway,总算可以把锅甩出去了
串联全链路的日志标识
前面说了,整个系统复杂度高,链路很长,如果你收集到的异常日志,只是没有收到后台的某个消息,当你理直气壮的去找模块A的后台同学的时候,他查了日志之后白了你一眼,你看你看,我消息发出去了啊,应该是别的模块有问题吧。然后你再找到模块B、模块C,得到了相同的答案,你说你能把锅甩给谁
本文当然不是叫你甩锅的啦,毕竟谁的问题,都是这个项目有问题,作为项目成员,你要有 owner 意识不是,不管是什么问题,都要尝试定位解决
这个时候,不但需要我们每个模块都有日志,还需要有一个能够串联全链路的唯一标识。也就是说,在设计之初,前后台以及各个关联方,要做好这个全链路的日志体系设计。这样一旦出现问题,就有迹可循了,很容易就揪出来有问题的环节
三、总结
解决偶现问题,经验至关重要,这需要慢慢沉淀积累,没什么好说的。然后剩下最关键的,就是完善的日志体系设计了,这需要整个项目组的努力,而你需要成为一个推动者
另外,程序的状态设计合理,异常路径考虑充分,也非常有利于预防这类问题的发生,毕竟,现在不管是 react 还是 vue,都已经是面向状态、数据驱动的编程了