大厂是怎样对待线上故障的?

安全 应用安全
为了保障安全,我们引入规范和流程,小心翼翼设计编码,如履薄冰测试发布,软件的结构和实现非常大的比重服务于稳定性,然而,纵使我们穷尽所能,也只能最大限度减少故障,而终究无法彻底消除故障。

 [[392933]]

本文转载自微信公众号「码砖杂役」,作者我不想种地 。转载本文请联系码砖杂役公众号。

软件测试有句名言:测试只能证明缺陷的存在,而不能证明产品没有缺陷。

为了保障安全,我们引入规范和流程,小心翼翼设计编码,如履薄冰测试发布,软件的结构和实现非常大的比重服务于稳定性,然而,纵使我们穷尽所能,也只能最大限度减少故障,而终究无法彻底消除故障。

企业为了保障交付和运营质量,往往会设置安全标准,制定事故惩罚规则,而这加剧了交付效率和系统安全的冲突。软件工程师摇身一变成了跟外科医生一样的高危行业从业者,我们被灌输了很多跟安全生产相关的知识,我们的认知被教育成某个样子,我们对于线上故障的观念根深蒂固而又深信不疑。

笔者在网游和互联网大厂工作过,它们对于线上故障有着截然不同的态度,这些不同对我造成了强烈的冲击,可以说我刚被教育成某个样子,等换了一份工作,又被教育成另一个样子,所以,我的认知在不断变化,而这些经历和变化使我相比别人有更多的思考和感悟。

如果说对于这个话题,我跟刚参加工作时有什么不同,那就是我逐渐意识到事情没有绝对,意识到我的认知不一定正确,而这或许是通往正确的道路。

所以,我把所见所感记录下来,力求客观呈现原貌,既不是要主张什么,也不是要批评什么,因为,相比于观点,事实才是更重要的,我更愿意倾听大家的观点。

一、网络游戏

我读研的时候在某狐做实习,在当时,某狐就是大厂,后来火狐工作室独立上市,对,就是纳市上市的CY。

我在《TLBB》做了一年半的游戏开发,这款游戏当时非常成功,PCU超80万,为公司贡献超过90%的营收。

TLBB通过流程管理软件管理需求和缺陷,这在当时非常先进。

策划提需求写文档,程序开发功能,提测,然后流程流转到测试那里。

测试的考核按BUG计件,而提测后的BUG数也会影响程序绩效。这样的制度设计能确保程序提测前做充分自测,从而去降低缺陷数,程序是功能的开发者,是白盒测试的最佳实施者,他似乎有一种天然的感知,预感那里会有可能出现问题,而且为了方便自测,他会想法设法去开发一些辅助测试功能,这又会提升测试的效率。

而测试为了绩效,也会竭尽所能去查找缺陷。但这个制度的一个副作用就是程序和测试关系经常很紧张,程序觉得地位不高,经常被测试干。

CTO为TLBB服务器制定了几条制度:

1. 简单至上,设计上直来直去,不过度设计;编码上不准用模板、不准用STL、不让用C++高级特性(比如异常、placement new等)。

2. 注重防御,安全优先于效率,任何一个函数都嵌入ENTER_FUNCTION和LEAVE_FUNCTION宏,多判断多检查,尽量不崩。

这种设计获得的一个显著好处就是项目代码简单,门槛不高,应届毕业两礼拜就能愉快上手,坏处就是程序性能不高,开发者天天跟数组和指针打交道,技术提不高,以致工作一年多之后发现看不懂开源项目,感觉自己是个智障。

游戏要求快速迭代,每周都会发版本,所以,从特征分支往主干merge代码有时间窗口,窗口关闭期内只能fix bug,新人前半年提交代码,会有人做review,相当于给儿童自行车后轮装2个支撑轮,之后便能自主提交,至于静态扫描、代码门禁,不好意思,没听过。得益于良好的制度设计和测试环节,TLBB服务器总体平稳,小问题偶发。

公司对线上故障有定级,但公司不怎么讲,所以大家感觉也不怎么强,要是某个程序不开眼捅了篓子,考核会受一些影响,次数多了,便会被贴不靠谱的标签,只能专业打杂。

后面我去了WMSJ,这个公司是几个清华学生做起来的。

07年,《WMSJ》凭借在3D上的卓越表现惊艳问世,随后又连续推出几款不错的游戏,成立三年便赴纳市上市了。

那时候CHI老板意气风发,千金买马骨,给应届生开出了1万5-1万8的高薪,哪年校招我碰上了,但是他们要求很高,我一面就阵亡,我另一个研究生同学去霸面被轰了出来。

这家公司的第一代程序员水平很高,至今我仍然认为是我工作中接触到最才华横溢的程序员,从客户端引擎到UI到数据库,整个游戏前后端+引擎,全部自研。因我做服务器,所以无法评价引擎、客户端技术。

光论服务器,它们的技术水平是很高的,当我在CY的时候,大家一直在Y,WM的大世界(无缝地图)到底是怎么做的呢?TLBB是分片地图,当我看完WMSJ服务器的代码,我被震撼了,那是一个非常精巧的设计,后来大热的BigWorld引擎在服务器设计上跟WM有共通之处。

相比TLBB,WMSJ完全是无规则的,没有任何明文规定禁止做什么,应该怎么做,只要编译能通过,运行不报错,就哦了。编码规范?交叉review?不需要的,代码门禁?封版?不存在的,线上故障处罚?没有的事。

但入职后一个半月,我除了看代码,没有任何工作要做,我一度怀疑领导对我有看法,借老婆生小孩的机会请1个月假表达不满,领导问我为何请这么长的假,我说反正也没事干,领导说,你没看新来的那个清华毕业生已经气定神闲的看了2个多月代码了吗?让我淡定,组织马上就有任务安排给我了。

通过这个项目,我学会到epoll模型、学会了多线程、学会了通过消息机制解耦、学会了COW、学会了lazy evaluation、学会了真正的OOP和GP(做抽象、泛化和扩展性)。

其中最大的思维碰撞来自于容错,之前TLBB的编码会做大量的容错处理,比如简单的get函数也会有enter_function/leave_function宏,会对指针判空,参数做合法性校验,会对返回值做检查,会log error等,大量的容错代码淹没了功能代码,导致完成同样的功能,需要多得多的代码。

但WMSJ的做法截然相反,它广泛的使用断言,函数专注于功能逻辑,对调用者有期望,如果不符合要求,不叨逼,直接崩,风格很硬朗,代码很紧凑。

我工作以来接受的教育不是这样的,这让我困惑,我找到了GameServer的主要开发者C总(技术VP、清华毕业的,他一个人写了超过60%的代码),公认的WMSJ最强架构师(不是我封的)。

我说:“TL服务器的风格是面向失败编程,能不崩就不崩,这样,程序才能有足够的韧性。WM服务器这样做不对吧!”

C总回答:“不是这样的,容错不是越多检查越多日志越好,核查只应该在边界进行,函数的实现者和调用者遵从某种契约,过多的防御并不能体现面向失败编程的思想,也不利于构建健壮的程序。崩会及早暴露问题,该崩不崩只会把错误埋得更深,导致缺陷更难定位,最终程序会变成藏污纳垢的混乱场,从而变得更加脆弱。”

“依赖假设,在代码被修改后,容易引起问题,线上故障是应该极力避免的。”我当时的认知没法接受他的解释,而是尝试说服他。

C总说:“assert在编译debug版本的时候起作用,而发布的时候,编译的是release版本,这其实是内严外松,在开发阶段及早暴露问题,上线之后才能更稳定,而且你遵照这样的规则编写程序会更清晰健壮,你多看几个开源项目就明白了。”

我当时被“你多看几个开源就明白了”给噎住了,因为我当时确实没看过什么开源项目,以致很多年以后,碰到同样的辩论,我也会用同样的一句话噎人。

WMSJ无规则,新人看一个月代码,这些事情,我丝毫没有夸张,所以,你看,虽然同为游戏公司(且为同种类型游戏MMORPG),但TL和WM采取了截然不同的策略,且在当时都取得了成功。

当年做游戏的时候,我们的开发任务很重,一般服务器组也就5-7人,2年内要写50万行左右的C++代码,4万行C++每人年,这个工作量是很大的,所以,其实很难走很重的研发流程,可以说,严格按流程走,基本上游戏没上线之前就死了。

但没走流程并不意味游戏程序员技术差,恰恰相反,大剂量的编码训练,往往使得大家编码水平较高,而且普遍很务实。

还有一个有意思的事情就是,我们曾经按照银行系统的要求去搞数据库,比如支持事务、支持回滚,发现既麻烦又别扭,直到有一天,我们顿悟,发现我们想多了,其实人最怕想多,也最容易想多,文科生一想多就容易出家,艺术家一想多就容易自杀,最终我们参考伯克利DB只用简单的3千行C++就写出一个Cache DB,其实它也够用了。

做游戏的时候,另一个体会就是我们曾经在稳定性设计上投入了很多精力,或者公司运营对稳定性提出了较高的要求,我们曾坚信这些是必要的,直到有一天,我们发现,事情可能并非如此。

比如有个游戏在封测期间,一天晚上宕机十几次,但疯狂的玩家竟然一边在论坛破口大骂,一边痴心不改的等待重启恢复,而统计数据表明,这款游戏的流失率很低,玩家好像真正在乎的只是游戏的趣味性,我们曾错误的以为稳定性是留存的大敌。

另一个例子是,某游戏因为程序缺陷,漏洞被玩家利用,而这个事情暴露后,消息在论坛、网络传播,导致大量吃瓜和看热闹的新玩家涌入,一个漏洞变成一个很好的运营广告,我们觉得出现故障,影响玩家体验,再给玩家发补助,这只是不得已的补救,但调查发现,这竟然是玩家喜闻乐见的,能极大提升话题热度和玩家活跃度。

二、互联网

说完游戏经历,说一下互联网经历。

我先后在TX和某里干过,先说说TX - WX,虽然WX的做法不代表整个TX公司的做法,但我觉得还是能反映一些问题,可供参考。

我在WX做过一段时间搜索的工程,就是WX 搜一搜,WX后台的服务基本上都是基于svrkit框架开发的,svrkit是一个RPC框架(开源名phxRPC),负载均衡、错误重试等框架都做了,基于该框架做应用只需要专注于业务逻辑。

当时WX搜索北京虽然有差不多60人,但绝大多数人都是做算法的,做工程的只有3个,2个做搜一搜,一个做看一看,我是其中一个。

要说TX怎么也是一个大厂了吧,按理说,研发流程应该也是很齐整,但坦白说,我们要上线一个应用真的没有那么麻烦,我们甚至没有专门的测试,我开发完一个功能,可能先灰度一台机器,观察5分钟,捞log看看,没有明显异常,然后我就灰度1%的机器,再观察1个小时,如果没有问题,我就灰度10%,再观察半个小时,如果还没有问题,我就梭哈了。

你看,一个更新,整个流程2个小时就可以搞定,是不是很麻溜?

那要是有问题怎么办呢?有问题,速度回滚,出故障,那就拉出来打板子,但这个板子其实一般不要命,有点自罚三杯的味道。

这个事,其实我一直不敢对外说,因为你这样说出来,会觉得丢人,会觉得low,一点都不高大上,跟同行见了面都不好意思打招呼。

WX一个技术主管跟我说过,他经常因为线上事故被通报批评,但没被罚过钱,有一次WX支付的故障,被大领导盘问,但即使这样,WX也没有想过通过加重流程去降低故障率。

他说这是WX的一个选择,WX认为业务失去快速迭代能力是不能承受之重,虽然线上故障有时候也会造成严重的后果,但WX对线上故障的容忍度较高,稳定性和敏捷性是矛盾的两级,很难兼顾,WX倾向了敏捷。

可见,TX,或者说WX并不是不清楚稳定生产的重要性,也不是不知道通过加重流程可以减少故障,只是在综合各方因素后,他们选择了保业务快速迭代,敏捷是互联网的命根子,不能丢。

有人跟我讲了另一个WX的故事,WX基本上在立项后几个月后推出了,因为很匆忙,其实后台有很多问题,比如内存泄漏,但他们没有马上选择去解决这个问题(或者说正面刚),他们选择了绕过问题,在服务100次后,进程自动重启,从而完美的解决了这个问题,这段代码后来被一个实习生review出来,把100改成1000,性能提升了很多倍。

说到这里,很多人一定以为WX的技术很弱,WX工程很渣,这跟事实不符,大家可以去TX开源看看,里面有大量WX开源的项目,我认为那些优秀的开源项目,是最好的证明。

再说说某里,某里则是完全另一番景象,某里行癫把稳定性比喻成木桶的底板,如果稳定性出问题,则滴水不留,所以,要求工程师在设计和开发软件的时候,坚持底板思维。

某里的开发人员每年都要过安全生产的考试,每年618、双11、双12、春节、38节、甚至两hui期间,TB都要提前很久封版,特别是双11,至少1个半月封版,封版期间任何更新都要走特批,所以,留给开发的时间窗口其实非常非常短。

每年都会集中培训安全生产常识,每年都会逐级开会强调安全生产重要性,安全生产大于天,这根神经绝不能松,都会提前做各种应急预案,假设XX情况出现要YY办,制作成手册,到时候出现异常,遵照执行,这些事情耗费了大量的人力财力。

但实际情况就是99.999%没用,完全是瞎忙活,大促期间都是集体出动,熬夜守班,再一起摆pos熬造型发朋友圈,你可能会说,这些是完全必要的,为的就是万一出现万一,有兜底方案,对,你说的对,这样的逻辑没人会不懂,某里人也是这么想的。

但任何事情都有一个度,这个度可视为一个平衡点,过犹不及,这是最朴素的道理。

为什么某里对安全生产这么看重,当然,首先,他们会从他们业务的特殊性进行一波分析,比如把TB自诩为国家基础设施,跟水电煤气一样,从各个角度阐述极端重要性。

但其实,最根本的原因大家没说,那就是谁出问题,谁3.25,而且还连坐,一出事基本上在,某里就没法做下去,处罚很重,而且真的会处罚很高级别的领导。

所以,在安全生产的“大是大非”面前,没人敢大意,没人敢做违背流程挑战zz正确的事情,结果上,某里的服务稳定性是否比TX强,我不知道,但迭代效率上,肯定是慢了很多。

最有意思的是,如果你跟某里人(特别是老人)讨论安全生产的问题,你会发现他们观点出奇的一致,他们坚信安全生产责任大于天,应该坚持零容忍,越严越好,但事情是否真的应该这样办?我不知道,但至少同为互联网的TX不是这样,而TX的业务不也发展的好好的吗?

我们很容易举出业务特殊性,比如电商可以举例说某个心脏病人因为网购救命药下不了单导致丧命,如果你制造了这个bug,相当于间接杀人,是不是很吓人?比如DD,它也可以这样说,因为APP出问题,导致打车的女孩不能及时呼救,被强奸继而被害,是不是也很恐怖?

其实这样的例子,游戏行业也可以举出来,比如某个孩子因为游戏卡副本,导致一怒之下,点了房子,导致灭门。

所以,没必要用这样的例子来强调业务的特殊性,因为是软件还是要尊重软件常识,回归本质,但业务有没有特殊性?有!而且我们必须正视。

比如电信业务,我们要把软件部署到别人的数据中心,我们要更新别人机房的程序有很多限制,这个跟互联网的软件确实有很大的不同。

这对我们的软件提出了更高的稳定性要求,这是显而易见的,但我们容易过于强调安全性,而忽视了对生产效率的影响,而对生产效率的副作用可能远比我们任何一个人想象的都大。

JD大东子曾总结几个商业成功的关键因素,其中之一,就是你可以做到更低的成本,或者做到更高的效率,所以,对于商业公司而言,生产效率,对应到软件的开发效率,成本控制,其实远比我们想象的重要,而我们却容易掉进顾彼失此的陷阱。

小结

我前面说我会阐述事实,而非陈述观点,很抱歉骗了你,其实完全没有观点的文章不值得写,史书还有观点呢,那笔者的观点到底是什么呢?

在一个个经历的故事里。

 

责任编辑:武晓燕 来源: 码砖杂役
相关推荐

2017-11-15 06:08:44

2020-10-12 08:45:25

程序员技术开发

2019-03-29 10:22:08

Linux系统故障技巧

2021-09-27 10:15:10

故障业务方电脑

2021-05-12 09:15:48

Facebook 开发技术

2015-09-22 16:13:50

2014-02-25 11:27:49

运维经验紧急故障

2010-08-25 09:21:57

网卡故障问题

2010-04-06 13:32:07

CDMA无线上网卡故障

2010-03-24 15:40:39

网管运维管理摩卡软件

2020-10-27 07:34:41

基站手机蜂窝网络

2022-12-22 17:46:19

2022-02-07 15:12:17

系统日志定位

2020-05-18 07:50:47

线上故障排查

2015-09-06 09:09:13

2014-06-20 10:34:42

开源

2015-11-10 09:09:23

代码程序员成长

2013-08-19 16:17:48

CIO

2011-11-25 09:48:04

天线无线

2024-03-28 08:13:51

GPTsOpenAI人工智能
点赞
收藏

51CTO技术栈公众号