12 CTO的艰难时刻:差点引咎辞职 极客时间:你去饿了么也属于空降的领导,刚进去会遇到什么挑战吗?

张雪峰:其实大家都专心做自己的事,我是没有感受到所谓的火药味或防御性。第一天我担心是有防御性的,但我一直没有体会到,只体会到他们对技术的追求,所以刚开始团队这块倒没什么,我主要遇到的挑战就是宕机,2015年那个夏天,我差点要引咎辞职,七月份各种故障纷至沓来。

极客时间:到引咎辞职这么严重吗?

张雪峰:宕机给我们造成的心理压力太大,那时候饿了么单量已经很大了,真是水深火热。我刚进去其实压力不大,因为我岁数大,大家都比较尊重我,Mark也比较尊重我。但三个月后我也开始被他挑战,被他骂,骂得很有道理,就是我们团队做得不好。

七月份我们基本一周要宕机一次,有些感知得到,有些感知不到。那时候我基本都是最后一个离开公司,都过零点的,因为我要确保没问题,其实也是有点拖延时间,就想怎么样才能完全破解。

当时觉得挺对不起公司的,而且Mark一开始是骂,到后来他也知道,我比他更着急,他也不骂了。所以15年那个夏天我真有可能就离开饿了么,后来反正不知道脑子怎么抽了筋,最后也没有提交引咎辞职报告。

当时我进来半年,也招了一些同学进来,跟新老团队融合得还可以。如果我选择离开,那这些人怎么办?所以后来想想还是考虑兄弟之情,咬咬牙硬挺过去了。

那时候就感觉自己真的快扛不住了。Mark有时候说两句,业务部门也会吼,但是都有尺度,但一线人员才不管,一线那时候把我们骂惨了,天天被骂成狗屎。

以前有个软件,比现在脉脉还要疯狂,叫无秘。脉脉职言区有时还是有顾忌的,因为有商业公司在运营,无秘是完全无官方运营的,就是一个畅所欲言的地方。那时候一天被骂得最多的就是:“拜托你们能不能招几个好点的网管?”。

一线说“招几个好点的网管”这样的话其实很朴实,他们觉得这些搞技术的都是天天吹空调、敲键盘,我们销售还要扫街,还要和美团“白刃战”,体力脑力兼有,然后一宕机还要被商户骂。

商户去骂也是对的,因为高峰期过了,消费者退单,宕机意味着做出来的饭只能倒掉,他也不知道要送给谁,浪费粮食啊,真的是很惨痛的教训。那时候大家可能认为赔商户钱就解决了,但其实商户心疼的是饭菜,眼睁睁看着好好做出来的几十份、上百份全部倒掉。

我们还要赔消费者,因为餐没送到。赔消费者是发红包,发红包的意思是说,这次我们宕机,下次你不要抛弃我们。除了商户和消费者,我们还要赔外卖小哥,因为小哥不能白跑。还要照顾销售的情绪,倒不用给销售赔钱,但我们要赔礼道歉。那时候真的很迷茫。

后来我们经常去一线调研,我也要送外卖的。一开始他们还不太敢说,我说咱们就当兄弟,有点江湖味,他们会给一些反馈。那个时候我是体会到兄弟之情,一线真的很苦,他们说得好听叫销售,但其实就跟扫大街的清洁工没什么区别,甚至更惨,清洁工还知道他是有固定任务,基本不会出问题。但销售要承担风险,万一宕机他要想怎么去赔礼道歉,甚至发生过有的销售快要给商户跪下去道歉。

极客时间:宕机的问题这么严重,你当时心里感受应该挺难的吧?

张雪峰:对,压力过大,好在没有到睡不着觉的程度,但第二天肯定又会想这些事。

虽然心里难,但我要能控制住情绪。我的个性还是能控制住情绪,因为确实是自己和团队要扛的责任,团队已经够拼命、够努力了,这个时候你去压团队也没用,我也不可能再去招一批人,招人也救不了火,而且招来的人还得磨合,所以只能是自己去想各种对策去弥补,主要还是靠时间。

绝顶高手是能控制住情绪,也能很快能消化掉,我是能控制住情绪,但我不能很快消化掉,我需要时间来稀释,以及想一些辅助手段去弥补。那时候,每天晚上为什么都要过零点才走,并不是说我必须最后一个走,就是待在公司去想一些问题。每天坐在座位上,电脑也看不进去,就想这些东西,所以主要还是靠时间吧,把这个不好的情绪稀释掉。

极客时间:你觉得自己是一个乐观的人吗?

张雪峰:对,我是偏乐观的,因为不乐观没法压制住自己的情绪。如果你是悲观又要压制情绪,一定会崩溃的。虽然我个人是乐观的,但是我对工作或者像安全性、稳定性这种事情,我会做最悲观准备,或者说设定一个较低期望值,这样不至于灾难或者故障来之时手足无措。因为很多时候一个人崩溃,是他根本没想过这件事,或没到他的期望值,才会出现很大问题,感觉难以释放。

从我的角度,这个期望值大概就是时间,时间可以解决这个问题。但首先你要能控制住情绪。

极客时间:后来宕机这个难题是怎么缓解的?

张雪峰:硬挺过来的,八月初就缓解了。当时主要两个地方:PHP、RabbitMQ有问题。

我们当时用了一个开源的消息组件叫RabbitMQ,这是个巨坑,不是说它软件本身不好,而是我们没有能力完全驾驭。另外,我们当时的PHP水平也还算可以了,包括后来我们找新浪的人(新浪用PHP比较多,饿了么也找过新浪PHP大牛尝试破局),他们也搞不定。PHP底层有引擎,当时每周一次的故障,几乎都是这个引擎带来的连锁反应,我们没能彻底搞定,然后大家都去读C的源码,赶鸭子上架,源码是能读懂,但就是搞不定,这东西可不是你加一句两句代码就能彻底解决的。

后面我们就用了各种work around,你知道work around就是绕过去甚至很ugly的办法,或者做很多补丁。其中一种补丁的学名叫补偿,比如你这个订单没过去,正常就丢了嘛,但丢了很严重,我们就设置个轮巡机制,有个Job,假设本来订单是5秒内响应,现在就是1分钟后发现有个订单漏了,再给你搞一次,用这样的方式(甚至包括人肉),做各种补救措施、补丁工具等。

物流宕机最可怕,因为我们这个业务是强耦合,不可能松耦合,就是要高内聚。物流宕机当时我们怎么做?人的智慧真的无穷,刚开始大家就用QQ群解决。因为我们类似广域网下的无数个局域网(不像淘宝,淘宝全国任何一地商家都可以服务任何另一地用户),我们可以划片区。他们那个QQ群就是骑手、老板、调度经理等人组成,骑手就送这几个商户。

比如说物流宕机了,但这时候订单是有的(商户挂掉那就没机会了),老板能做出餐,但是没有办法传递到小哥怎么办?小哥在QQ群里说“我没接到单,你有多少单了?”商户说“我已经接了10个单,你快来。”然后就在QQ里面传单号。那时候微信还不怎么流行,小哥还是喜欢用QQ。但后来宕机问题解决,终于可以下线QQ work around了。

极客时间:有点曲线救国的意思。

张雪峰:是这个意思,后来我发现物流系统还有个很大的问题,搞物流系统这批同学,就是另一类极客。饿了么刚开始拆分服务,物流拆分得很夸张,直接同步变异步了。我说你们犯了一个错误,叫“为了异步而异步”。

大家以前的代码(交互)尽量都是一路撸到底嘛,直接写完,这个叫单体。后来搞微服务就要拆开了,结果他们不光拆开,拆开之后,还要用消息通知。我举个不太恰当但大家明白意思就行的例子,比如说算工资,本来可以直接算出来,他们非要先送一个你的职级,再送一个你的社保基数,然后送过来之后还不是马上给你,你要自己去取,我只是通知你有这个数据了。你取过来之后慢慢算,算完之后再推给另一个涉及工资计算的模块,诸如此类。物流同学就是用类似方式,他们真的把异步做到了“极致”(饿了么价值观:极致、激情、创新)。

但是他们做异步的初衷是什么?是因为物流的量很大。以前宕机是因为量很大,用同步的话服务器撑不住,所以就改异步。他们说至少可以缓和五秒钟,但后来我发现这五秒钟没意义。

我自己也体验过,比如我点个外卖,提交订单之后习惯性去刷一下,看看商户有没有接单,然后过一分钟看看骑手有没有接单。还要看地图,有时候看到小哥明明经过我这了,怎么先去送另一个人了?可能很多人都有这样的疑问,这个不能怪骑手,也不能怪系统,有各种原因,此处暂时不表。

大家都会去刷,后来我们发现用户在饿肚子时的心理承受能力就是三到五秒(淘宝、携程没这问题,大家对订单或物流状态变化的容忍度高很多),你是通过异步让这个订单不至于当场爆掉,但你延后五秒之后,堆积起来也很厉害,东西多了之后,最后还是爆掉,你只是让用户前五秒感觉系统没有宕机,但最终结果还是宕机。最后我们异地多活搞出来,几乎就没有大的事情了。

极客时间:其实这一次困难挺过去之后,后面再遇到难题,相对来说你就比较从容了。

张雪峰:对,那时候我自己心里有障碍,不好过去,至少刚开始不好过去。我和老婆说,估计要在公司旁边旅馆住几个月,直到彻底解决宕机问题。那时候,大家也看到我的焦虑,他们也竭尽全力,但宕机这个事情你不能去硬搞,比如每天都去揪每一个(可能引起宕机风险)模块的每一行代码写得怎么样,这个会出乱子,也极其耗时,ROI 极低。在当时那么紧迫时局下,我只能用另外的方式(如:局部技术改造、局部架构升级等)去缓解。当然了,中长期解决方案还是团队整体架构能力和代码质量提升,这里先不展开了。

那时候还没到根治的时候,因为当时不要说异地多活了,灾备还没有呢,所以只能去缓解。你如果要根治下猛药,那我那会真的可能实现了CTO里面“O”的价值,但这个就是负面价值了,会导致公司出问题。

如果那次我引咎辞职,汪渊是可以临时顶上去,但真的,就不说团队可能散架吧,后面凝聚力肯定会有大麻烦,因为汪渊已经去搞产品了,大概率还得再找个CTO过来。

极客时间:除了这个对你来说是个坎儿,还有没有其他的艰难时刻?

张雪峰:还有一次是在阿里,出过一次事故。当时就是异地多活出了事情,理论上异地多活能切的,但是因为一个开源组件的问题导致出了一个大事故。

我后来也反省,我是有责任的,因为这个组件当时做过一次交接,本来是在中间件团队,后来交接到另外一个团队。但交接的时候,只做了个口头交接,没有立字为据,没有指定说这个就是你来管,这也是我们当时不够精细的地方。所以最后很难判责,确实判罚谁也不好说。

而且其实任何故障都会有端倪,没有无缘无故的故障。在那次事故发生前,其实有一些端倪了,只不过比较隐蔽,只有极少数同学发现了,但他们也没意识到持续堆积会造成重大问题。

后来我们复盘发现,当时出了故障,不做切换反而不会引起大错,最多就牺牲一小部分流量。但是按照SOP(标准作业程序),确实应该切换。恰恰是这个开源组件命中了一个Bug,所以导致切换引起了风暴,细节我就不多讲了,但其实事故发生前就有端倪了。

出了这个事,我跟建刚商量,我说建刚你做好准备,扣你全年的奖金,我自己降一级,我们跟公司主动一点。跟公司汇报完了,昆阳火比较大,他说你凭什么自己申请降级,你没这个资格要求自己降一级。他意思是说你自己感觉你有担当,但他们(包括CEO、CPO)不认为我这时候这么做是合理的。

他们灵魂拷问我说,“雪峰,我知道你有担当,你想帮团队扛下,你想保住他们,但是你有没有考虑过,进了阿里之后,如果一线工程师不为一个Bug负责,而且是他已经看到可能有问题,只是没有警觉,那你认为今后组织再扩张10倍,还能不能Run下去”,他说的是有道理的。他认为我是江湖气,当然我是有一点,但其实我也感觉自己没做好,不完全是为了帮团队顶锅。

后来我就只能出面去跟一线工程师谈。那位一线工程师对我们有汗马功劳,是一位非常优秀的员工,只是因为组织转变、汇报关系转变,包括责权不清晰等等问题,他自己也郁闷,所以就没怎么上心。我跟他说从结果角度你要承担责任,你要承担工程责任,我承担管理责任。

他认这个理,但是他也感觉比较委屈,最后他跟我吃顿饭,说自己也想通了,我说我对不起你。我们对他有一些小的处罚(不是劝退),但后来他主动提离职,其实相当于我劝退他,我认为这也是对我的一个考验,这也是我另外一道坎儿。

当时如果这件事被披露到网上,工程师们肯定会非常愤怒,说不应该惩罚一线工程师,这全应该你们Leader来担,但一线工程师在阿里也是要担一定责任的,不会让你降级或离职,但至少会对你的年度绩效有影响,比如绩效不能3.5,不能参加晋升,这种处罚也是有。我们也类似,并不是要让他辞职,基本都是通过绩效反映的。

我认为HR说的是有道理的,对于一个组织来说,确实应该这么做,特别是对一个越来越大、越来越正规化的组织,是应该这么做,否则没有规矩不成方圆,我再心疼他,他有再大的汗马功劳,也得这么做。跨过这个坎,对我来说也很不容易。

极客时间:我可以理解劝退别人这件事对你是一个坎儿吗?

张雪峰:不是,我也劝退过不少人,但我感觉劝退我认为几乎没过错、又曾立下汗马功劳的优秀同学,是一个坎儿。

极客时间:如果那个时候不是在阿里,而是在没有被收购之前,遇到这样的事情,你会怎么做?

张雪峰:没有收购之前的话,可能我就跟Mark说我降级,Leader他们就象征性的处罚,因为这个事情扯不清了已经,没有立字为据。所以责权不清这是我要反思的,也是我的责任。

所谓协调,相当一部分都是这类问题。表面看,这可能是件小事,组织架构有调整我也知道,但我在规范设计或制定上有漏洞。其实PMO已经帮了我很多,他们制定了很多细节,但我在这件事上确实有责任,而且引起了很严重的故障。但经历过就有收获嘛,你没经历过,后面还是会有类似的情况发生,尽量不要在同一个地方犯两次错。所以,我都是一路犯错过来的,一路被挑战。

参考资料

https://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/%e8%b6%85%e7%ba%a7%e8%ae%bf%e8%b0%88%ef%bc%9a%e5%af%b9%e8%af%9d%e5%bc%a0%e9%9b%aa%e5%b3%b0/12%20CTO%e7%9a%84%e8%89%b0%e9%9a%be%e6%97%b6%e5%88%bb%ef%bc%9a%e5%b7%ae%e7%82%b9%e5%bc%95%e5%92%8e%e8%be%9e%e8%81%8c.md