直道超车

最近几天都在修case。其实不是我的case。都是其他那些team的。自己不看,总是怪infrastructure。那只好我自己来了。

好像中国和美国的程序员都是类似的:自己的用例失败了,总是不会先从自己身上找原因,总是先blame infrastructure。总是要别人一而再再而三的把铁一样的证据放在他们面前了,他们才会承认是自己的用例有问题。

承认了自己用例有问题还要继续找借口:哎呀,你们这个工具不好用啊,排查起来很辛苦;哎呀,你们这个工具不好用呀,我要单独跑一下用例很辛苦;哎呀,你们这个工具不好用呀,能不能把失败的用例给自动重跑一下呀;哎呀,你们这个工具不好用呀,能不能智能一点,做一下智能分类、智能诊断。就是不肯乖乖的把自己的case修修好。

要不说姜还是老的辣。今天修的这个case,那几个兄弟之前都挣扎过了,都挣扎不出。我从中午开始看的,看啊看,看啊看,都是从来没看过的代码。看到晚上,被我灵光一现看出来毛病了:有个地方把now()转成“US_EASTERN”时区的时间。当时就觉得这个地方很fishy。

Fishy 在字典里的意思是 arousing feelings of doubt or suspicion,翻成中文就是:这里看着很可疑,这个地方感觉怪怪的,这里感觉不太对劲。

这不有个故事吗。说有台机器坏了,谁都搞不定。最后请了个老师傅来。老师傅看了看,把一个螺丝拧紧了,机器就好了。老师傅收了1000块钱,人家嫌贵。老师傅说,拧一个螺丝只要10块,但剩下990块是知道拧哪个螺丝。

老程序员就是值这个钱。改一行代码看上去很简单,只值10块钱。但能看出来要改哪一行代码,就凭这个,老程序员的工资就比新兵蛋子高。

写这个“US_EASTERN”的估计也是一个新手,没吃过timezone的苦头的,顺手就写了。他这一顺手,后面好几个人好几天时间就没有了。要是再到线上出问题,或者等到屎山已经很高了再搞技改,那就是动辄几百人日的代价了。

“US_EASTERN”的问题就是:每天有一个小时的时间,当“US_EASTERN”还是10月19日的时候,真正的纽约当地时间已经是10月20日了。就差这一天。每天这一个小时里面这个case必败。大家之前看不出一个头绪,看不出什么pattern,原因之一也是之前败的并不频繁。这是不是从另一个侧面也说明,我司在西海岸的同学们到晚上九点提代码的人就不多了。

这两天还修了一个很有趣的case。有个case,偶尔会败。这个case其实没干啥,就是在本地的DynamoDB里面插好多条假user,然后再读出来,看看对不对。但有时候在PutItem的时候会报错,报“Cannot do operations on a non-existent table”。好几个人看了,看不明白,没头绪。

那天我看了一会儿,也没看出来为啥。但我就看到一个地方很fishy:这个用例,用一个for循环插数据,for循环循环了1000次。我看到那里的时候就眉头一皱:有必要吗?

我就去问这个用例的原作者。还好这个用例还算新,八月底加的,作者还在。作者说,其实1000就是随便放的一个数字,到底是 100还是1000,对这个用例来说并没所谓。我说,那要不我帮你改成100吧。因为这个case时间太长了,现在要跑八九秒钟。我改成100,估计不到1秒就跑完了。他说可。

于是我就路见不平的改了。把循环1000次改成了100次。然后我发现,改完以后,这个用例不flaky了,“Cannot do operations on a non-existent table”彻底消失了。敢情这背后的原因就是循环太多了哇,把本地DynamoDB给压坏了。

那个作者还算心思缜密,还问我,这是不是意味着在线上也会有性能问题。我说,也许吧。也许只是本地DynamoDB比较搓,云上的可能就没这个问题了。你要是实在不放心,去云上直接测一测。总之,就别在CI里面跑压测了。

用例不稳定,基本上每个公司都有这个问题。很多人都想走捷径,老是把“弯道超车”挂在嘴上,想搞个什么大招可以一下搞定,或者想另辟蹊径,绕开这个问题,或者搞个自动重跑什么的先对付着。其实,用例不稳定的问题,只有一条路:好好写代码。不稳定的用例好好分析,好好修,修了就修修好,不要东加一个sleep西加一个retry的糊弄过去。

这就和减肥是一样道理。不想改变不健康的饮食习惯,但还想减肥,那是不可能的。局部减脂,不存在的。代餐,都是智商税。减肥的办法,就是做正确但艰难的事。

Comments on “直道超车

Leave a Reply