背景
百科V5版重构,实际上是百科有史以来(06年4月20日上线,产品发展的第9个年头)第四次整体性的重构,重构共耗时两年,按先后次序从展现,底层存储到核心提交依次重写并分步接入,替换原有核心。在这个过程中,新老系统并行运行,在不断的迭代过程中下线老的子系统。
至于为什么在九年时间内进行四次重构,原因很直接,就是之前重构中没有解决系统状态不佳的根本问题——过度复杂,第三次重构甚至还加剧了这个问题。
V5版重构耗时两年,其中核心系统(词条的展现,编审提交,存储)共耗时一年,周边子系统迁移耗时一年。重构完成后系统状况提升明显,核心系统代码量仅有原来的20%,浏览及提交性能都有数十倍甚至几十倍的提升。
一点点讨论
1. 参与此次重构最深的感触是什么
看到这个问题,竟一时不知从何说起,感觉此时像极了很多电影中,回忆画面开始前的桥段,男主沉默半晌,深深的吸了一口,又慢慢的吐出,伴随着烟雾的缭绕,时间又飞回到了两年前……
- 『卧槽代码写的这么烂,都特么干不下去跑路了,把哥拉过来给他们擦屁股……居然还有加薪升职的,应该拖出门外痛打!!』
- 『对同义词重定向的问题,我能想起的最适合它的画面:「孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说,“对呀对呀!……回字有四样写法,你知道么?”」,究竟是用户真正的需求,还是特么你自己所谓的需求?』
- 『在一片和乐的氛围中,众人亲手掐死了这个产品,却还在四处寻找刽子手』
- 『都二十七八岁,谁不愿意享受大好时光,良辰美景,花前月下,谁特么愿意天天加班看这坨**一样的代码』
- ……
(压迫至极吐槽,不代表本人主流价值观)
我也惊讶回想起这段时间,不那么愉快的时光占据了绝大多数,甚至自己失眠在床上辗转反侧的时候,脑子里挥之不去的就是这些念头。而与之相对的是,重构上线的成功,各项技术指标的大幅提升,以及自身技术上的成长,并没有带来巨大的成就感,持续的喜悦,以及额外的回报。快乐的时间和那些煎熬的时光相比,总是短暂的,甚至感觉,不那么值得一提。
但是,这和我在知道做过的重构,感觉完全不一样!为什么同样历尽艰辛,克服重重障碍完成了重构,回想起来感觉完全不一样?
我想,这应该就是上面这个问题的答案:
『粗糙技术/需求的巨大破坏性』
(用粗糙是为了尽量中性客观一点的描述,避免强烈的主观色彩,私下介绍这里会用一个「烂」字)
其破坏性体现在几个方面:
- 其一,对人/团队态度的消极影响:相信从上面的描述可以感觉出多么负面的感情,当然以自己的感觉作评价有自说自话的嫌疑,不妨看下研发人员的流动性,待接盘后的那个年关,老研发相继离职(用争先恐后可能也不为过),走的时候都有一种解脱的感觉,团队濒临断层,老系统只有一个老QA了解一些。
- 其二,对新人成长的影响:观察同时期兄弟产品线的新人,可以明显发现两边成长的差异。zhidao的重构和baike V3重构在差不多相近的时间段启动,zhidao早已完成预期目标,系统调理清晰,同时培养了不少新人,大多都成了独当一面的靠谱工程师,而baike这边则陷入了过度复杂的泥沼,不得已再次展开又一次的重构。同时期入职的新人在编码习惯,系统模型,一些基本概念的理解上都不甚理想。
- 其三,对产品的影响:重构开始前与PM的通气会上,PM举双手赞成,原因很直接,就是因为做什么都做不了,做什么都很慢,一做活动就崩溃,用户天天有投诉,bug提也提不完。这种环境下,PM即便有好的idea,运营有再强的推广能力,也没有什么卵用。
- 其四,对公司的影响:极大的增加了成本,包括人员,机器,时间等各方面。以机器为例,老baike前端上百台机器仅勉强能支撑每天的访问量,同时期访问量差不多的知道,同样也使用PHP,前端仅有寥寥二十余台机器,即便baike属于重前端,这个数量也决不至于4倍于zhidao,baike毕竟还有页面缓存扛着流量呢。按两倍算,也多用了30多台机器,每年至少因为粗糙的技术多花100多万(估算),多花的这些钱,用来改善待遇/福利可好?
最严重的后果就是导致这个产品死掉,散落一地鸡毛。『众人亲手掐死了这个产品,却还在四处寻找刽子手』
2. 这次重构成功吗,为什么?
从技术的角度看,这次重构是非常成功的。暂且不论上线后各项技术指标的成倍提升(详见PPT),从两件具体实例看,一是open-bugs邮件组,从最开始每天爆满,到现在一个月也没几封,没有产品或研发同学每天的时间都耗在修不完的bug上,能集中精力去做业务开发,这就是一个非常好的转变。二是编辑大赛的运营活动上看,老系统一天提交上限也就<10W,超过系统就开始延迟,体验极为恶劣,新系统支持百万量级的提交,后面运营活动的数字都非常漂亮,是由审核系统的重构来提供保证的。
此次重构,让濒临崩溃的系统重新回归正常的状态。
犹如大病初愈的病人一样,有没有问题呢,还是有的,此次重构基本重写了一个百科,但之前的底子太差,数据层面的混乱完全修复几无可能,例如模块的数据,仍然是一个复杂的数据包。这是后续系统发展的一个风险,但凡涉及到这里的变动,还是会很复杂。例如编辑器,前端系统的一个风险点。
其它方面,看法可能就各有不同了,对于我来说,最恰当的表述可能就是『重构多少事,都付笑谈中』了
3. 理想的架构是什么样子?
加个前缀,我眼中,理想的架构用一个词描述就是『简单』,两句话描述就是『主干清晰,结构简单』。
为什么说理想的架构最典型的特征是简单,举个例子,IPhone,大街上随处可见,为什么这么贵大家都还愿意买,就是因为简单,或者另一个词,好用,即便是老人或者小孩儿,都不用学,拿着就会操作,基本上直觉上的反应,就该是这个样子的。如果把一个系统也做到这个程度,随便让个人来看,稍微说两句就能明白,让他也觉得这件事就应该是这个样子的,那差不多就做到了简单的程度。
但要做到这个简单确不是件容易的事,《黑客与画家》里面给了很好的解释,当想把一个事情做简单的时候,就不得不触及这件事的本质,而探索一件事的本质,是很难的事情。
『主干清晰,结构简单』是自己总结的两句话,对于业务系统,新上手的人,最迫切的想抓住两条线:
- 控制流:这个系统主要做了什么,都包含哪几步,每步大概做了什么事情,画出来就是系统/模块的流程图。即便需要了解细节,也能很快定位到相应的代码块。理想的控制流,要足够的清晰简单,让人凭借相关的注释和名称,就大概能了解到相应的功能。不拖泥带水,不阴暗晦涩。
- 数据流:了解了功能接下来就需要掌握数据从何而来,需要做怎样的加工才能完成我想要的任务。数据的结构和变换应尽可能的简单清晰易扩展。杜绝复杂的数据封装,百科的系统复杂,很大程度上就是因为复杂的数据构成,不得不写大量晦涩难懂的代码块去加工数据成各自想要的格式,毫无逻辑可言。
当你想简化上面两条线的时候,软件工程上常常讲的两个高内聚/低耦合也就会逐渐进入你的意识中了。一个好的系统蓝图就会慢慢构建出来。
4. 如何做一个好的研发工程师
字如其人,码亦如其人,编程语言作为另一类语言,很多时候也能反映出coding的人当时的心态和态度,设计优美,代码写的工整,细节处理的漂亮,于人于己都是一件好事,常常说有些工程师值得尊敬,有些工程师不值得尊敬,大多数判断来源于此。
相信能坚持做到这一点,对于设计,开发以及交付的各个环节,心中都会有个高那么一点点的追求,努力把事情做到能让自己觉得满意,而不是仅仅实现了这个功能,完成了这个任务而已。