“我真正担心的是补丁的流程,工作流程比代码更重要,”Torvalds 说。“如果你有正确的工作流程,代码就会自行解决,如果出现错误,我们知道如何处理。”
他承认他现在不清楚内核中的每一行代码,但这并非是一件坏事。Torvalds 说,内核的庞大规模导致了它日益复杂化,而开源模式是内核成功的核心。因为在复杂的世界里,应对复杂性的唯一方法是公开交流想法。你不能在一个封闭的环境中管理复杂性。
自 1992 年起 Linus 开始采纳其他开发人员的补丁,如今,Linus 拥有一个实力超群的内核维护小组,Linux 系统的协助模式是 Linus 负责总体的协调和沟通,他会对接十余名核心贡献者,每个人都有自己负责的具体领域和项目内容,每次有新的开发任务时 Linus 会将它分配给对应的人;而这十余位核心贡献者又有各自的熟知并信赖的高手小团队。Linus 只需知道将任务交给他自己团队中十余名成员哪个人即可。
Dirk Hohndel 曾经问 Linus,这样的开发模式是否可持续?Linus 笑着回答如果当前团队中有程序员变老变胖(感觉像在说自己哈哈)不想继续做下去的话也没有问题,因为会有新的程序员补充进来。Dirk 又追问 Linus 道,在内核不断提升迭代的过程中,是不是你具有着绝对的决定权?Linus 回答到“不是的”,他发自内心地鼓励大家按照自己的需求建立 fork,如果最终这样的想法有良好的结果做证明,其精华部分就会被吸收到 Linux 内核项目中。Dirk 对此总结,当今的分支发展再吸收代码的模式其实反映的就是 Linus 本人或其团队的决定性。
不难看出,Linus 等技术大神对于软件开发的流程都非常看重。一个设计完备、良好运转的软件开发流程,对于提升软件工程的效率,解决突发问题都大有裨益,那么问题来了,怎么做呢?我们看一下 Facebook 的经验案例。
Facebook 是世界上最大的社交网站,早在 2017 年,其月活就超过了 20 亿,是微信的两倍还多。支持这样一个站点的运行,还要不断发布新的功能,Facebook 的工程师是如何做到这一切的?
Facebook 的工程师们不会像传统软件行业那样使用瀑布模型进行开发,他们不断地开发新的功能,并迅速上线,让用户能够访问到这些新功能,这就是大家口中经常提到的持续部署(continuous deployment)。在他们看来,Facebook 的开发永远没有到头的那一天,代码库在不停地增长着,代码随时间呈现超线性增长的趋势。
在 Facebook,所有前端工程师都工作在同一个稳定的分支上,这也能加快开发速度,因为省去了繁琐的分支合并过程。在日常开发中,每个人都用 git 在本地进行开发,当代码就绪之后,就会将它推送到 SVN 上(之所以是 SVN,这是出于历史原因),这样就很自然地区分开了开发中的代码和可以上线的代码。
但是为了保证网站的稳定运行,并非是工程师将代码推送到 SVN 上,认为可以上线,代码就能发布上线的。Facebook 采用了一种兼顾了速度与稳定性的做法——将每日发布与每周发布结合到一起。所有的代码变动默认是每周发布,每次发布会包含相对比较多的变更,在每周日的下午,代码会被发布工程师推送到 SVN 上,随后会进行大量的自动测试,其中包含很多针对正确性和性能的回归测试,这个版本会成为 Facebook 员工内部使用的默认版本,正式的发布通常被安排在周二下午。
发布工程师会为每个工程师的历史表现打分,内部称为“Push Karma”,比如那些代码经常出问题的人,分数就会相对较低,他们的代码自然也会受到更多的“关照”。这样做的目的是控制发布的风险,而非对某人做出评判,因此这个分数是保密的。除此之外,越是大的变更,或者在 Code Review 时讨论越是多的代码,也是风险较高的地方,同样会受到更多的“关照”。
在被纳入发布之前,代码已经经过了开发者的单元测试和 Code Review,在 Facebook,Code Review 是非常重要的事情,他们使用名为 Phabricator 的工具进行 Code Reivew,该工具是和代码版本管理整合在一起的。
在大量的自动化测试之外,每位员工在内部使用 Facebook 时也相当于进行了高密度的测试,每位员工都能报告自己发现的问题,写代码的人多了,代码增长的快了,相对而言,对代码进行测试的人也多了。
在性能方面,Facebook 使用 Perflab 对新老代码的性能进行对比,如果新的代码性能不理想,并且开发工程师无法及时修复,那么相关代码就会从本次发布中剔除出去,待问题修复后再进行发布。每个小的性能问题都是不容忽视的,因为小问题会很快累积起来,变成影响容量和性能的大问题,Perflab 能通过图表的形式直观地展现系统的性能。
Facebook 每周的发布是分阶段进行的,首先是 H1,即部署到仅有内部访问的服务器上,进行最后的测试,很多公司也称其为“预发布”;随后是 H2,部署到几千台服务器上,开放给一小部分用户;如果 H2 阶段没有发现问题,则进入 H3,部署到全部服务器上。
如果在这个过程中发现问题,工程师会立即进行修复,随后重新开始分阶段的部署。当然,也可以选择回滚代码,有两种回滚方式——常见的是回滚某个变更及其依赖的文件,另一种则是回滚整个二进制包。
这个“准持续(quasi-continuous)发布周期”的最大优点在于:它迫使我们开发下一代工具、自动化和流程,以使公司能够扩大规模。
在发布时,与变更相关的开发者必须在线,发布工程师会通过 IRC 机器人进行确认,如果人不在,那么他的变更会被回滚。这样保证了问题能够在上线之初就被快速发现并修复,当然,想在这么大的一个系统里及时发现一些问题有时也是很困难的,所以 Facebook 会结合内部工具 Claspin 和外部的信息源(比如 Twitter)持续地监控系统的健康状态。
通过 Gatekeeper 系统,工程师们可以方便地控制多少用户能够访问特定的新功能,筛选的条件可以是地区,也可以是年龄,在遇到问题时也能迅速关闭某个功能的入口。在 Gatekeeper 的帮助下,工程师们能方便地进行 A/B 测试,藉此迅速收集用户的真实体验,对产品做出调整。不要忘了,在 Facebook,是工程师来选择自己做什么的,那么工程师们肯定是选择把东西做出来,看看用户的反应,而不是坐在会议室里和一堆人开会去猜测用户想要什么。
现在,Facebook 有数千名名开发工程师,但却没有独立的测试工程师。每位工程师都可以看到全部的代码,并且能提交补丁,或者提交详细的问题描述。工程师们需要自己编写详尽的单元测试,他们的代码还要通过所有的回归测试,并能支持后续的各种运维工作。
除了要对自己的代码负责,他们还要面对各种巨大的挑战,往往要针对多种解决方案进行大量试验。比如,当时为了解决 PHP 的性能问题,有 3 个不同的方案同时在进行开发,当某个方案的负责人发现另一个方案更好时,他们就会停下来;最后 HipHop 胜出了,但另两组人的精力也没白费,他们提供了重要的备份能力。
看了 Facebook 的经验以后,你有什么感想?
你能分享下你现在公司的软件开发与管理流程是怎样的吗?
今日荐文
点击下方图片即可阅读
Facebook 的工程师文化是怎样的?
文章评论