Facebook是世界上最大的社交网站,有超过10亿用户每月至少要登录一次,他们每天要上传超过25亿内容,支持这样一个站点的运行,还要不断发布新的功能,Facebook的工程师是如何做到这一切的?目前就职于Facebook的极限编程创始人Kent Beck在近期发表的一篇与别人合著的论文里向大家详细介绍了Facebook的开发与部署流程。显而易见,Facebook的工程师们不会像传统软件行业那样使用瀑布模型进行开发,他们不断地开发新的功能,并迅速上线,让用户能够访问到这些新功能,这就是大家口中经常提到的持续部署(continuous deployment)。在他们看来,Facebook的开发永远没有到头的那一天,代码库在不停地增长着,目前已经有超过1000万行代码,其中850万是PHP代码,代码随时间呈现超线性增长的趋势。在Facebook,所有前端工程师都工作在同一个稳定的分支上,这也能加快开发速度,因为省去了繁琐的分支合并过程。在日常开发中,每个人都用git在本地进行开发,当代码就绪之后,就会将它推送到SVN上(之所以是SVN,这是出于历史原因),这样就很自然地区分开了开发中的代码和可以上线的代码。但是为了保证网站的稳定运行,并非是工程师将代码推送到SVN上,认为可以上线,代码就能发布上线的。Facebook采用了一种兼顾了速度与稳定性的做法——将每日发布与每周发布结合到一起。所有的代码变动默认是每周发布,每次发布会包含相对比较多的变更,在每周日的下午,代码会被发布工程师推送到SVN上,随后会进行大量的自动测试,其中包含很多针对正确性和性能的回归测试,这个版本会成为Facebook员工内部使用的默认版本,正式的发布通常被安排在周二下午。发布工程师会为每个工程师的历史表现打分,内部称为“Push Karma”,比如那些代码经常出问题的人,分数就会相对较低,他们的代码自然也会受到更多的“关照”。这样做的目的是控制发布的风险,而非对某人做出评判,因此这个分数是保密的。除此之外,越是大的变更,或者在Code Review时讨论越是多的代码,也是风险较高的地方,同样会受到更多的“关照”。在每周发布以外,其他工作日每天会有两次小发布,大多是些非关键性的更新,或者是些Bugfix,极端情况下会进行更多的发布,甚至是在周末进行发布。在被纳入发布之前,代码已经经过了开发者的单元测试和Code Review,在Facebook,Code Review是非常重要的事情,他们使用名为Phabricator的工具进行Code Reivew,该工具是和代码版本管理整合在一起的。在大量的自动化测试之外,每位员工在内部使用Facebook时也相当于进行了高密度的测试,每位员工都能报告自己发现的问题,写代码的人多了,代码增长的快了,相对而言,对代码进行测试的人也多了。在性能方面,Facebook使用Perflab对新老代码的性能进行对比,如果新的代码性能不理想,并且开发工程师无法及时修复,那么相关代码就会从本次发布中剔除出去,待问题修复后再进行发布。每个小的性能问题都是不容忽视的,因为小问题会很快累积起来,变成影响容量和性能的大问题,Perflab能通过图表的形式直观地展现系统的性能。像Facebook这样一个网站,每周发布自然是分阶段进行的,首先是H1,即部署到仅有内部访问的服务器上,进行最后的测试,很多公司也称其为“预发布”;随后是H2,部署到几千台服务器上,开放给一小部分用户;如果H2阶段没有发现问题,则进入H3,部署到全部服务器上。如果在这个过程中发现问题,工程师会立即进行修复,随后重新开始分阶段的部署。当然,也可以选择回滚代码,有两种回滚方式——常见的是回滚某个变更及其依赖的文件,另一种则是回滚整个二进制包。Facebook在四个不同的地理位置分布了大量的服务器,整个发布的包大约有1.5G,一般需要20分钟来完成整个分发。为了实现这一点,分发过程中分发使用了BitTorrent,分发时也会考虑到机架和集群的亲缘性。自从Twitter开源了他们的基于BitTorrent的发布方案Murder后,通过BitTorrent进行发布已然成为了业内的标配。在发布时,与变更相关的开发者必须在线,发布工程师会通过IRC机器人进行确认,如果人不在,那么他的变更会被回滚。这样保证了问题能够在上线之初就被快速发现并修复,当然,想在这么大的一个系统里及时发现一些问题有时也是很困难的,所以Facebook会结合内部工具Claspin和外部的信息源(比如Twitter)持续地监控系统的健康状态。通过Gatekeeper系统,工程师们可以方便地控制多少用户能够访问特定的新功能,筛选的条件可以是地区,也可以是年龄,在遇到问题是也能迅速关闭某个功能的入口。在Gatekeeper的帮助下,工程师们能方便地进行A/B测试,藉此迅速收集用户的真实体验,对产品做出调整。不要忘了,在Facebook,是工程师来选择自己做什么的,那么工程师们肯定是选择把东西做出来,看看用户的反应,而不是坐在会议室里和一堆人开会去猜测用户想要什么。Kent Beck在文中表示:仅有方法论和工具是远远不够的,因为它们总是会被误用。所以,拥有鼓励个人责任感的企业文化是很重要的。现在,Facebook有大约1000名开发工程师,仅有3名发布工程师,没有独立的测试工程师。每位工程师都可以看到全部的代码,并且能提交补丁,或者提交详细的问题描述。工程师们需要自己编写详尽的单元测试,他们的代码还要通过所有的回归测试,并能支持后续的各种运维工作。除了要对自己的代码负责,他们还要面对各种巨大的挑战,往往要针对多种解决方案进行大量试验。比如,当时为了解决PHP的性能问题,有3个不同的方案同时在进行开发,当某个方案的负责人发现另一个方案更好时,他们就会停下来;最后HipHop胜出了,但另两组人的精力也没白费,他们提供了重要的备份能力。在文章的最后,还提到了Facebook的新兵训练营制度,关于这一点,Facebook的早期员工王淮在他的《调教你的新工程师 – 谈新兵训练营》中做了详细的描述。关于Facebook,有很多值得深入学习和探讨的地方,比如他们的工程师文化,比如上文提到的新兵训练营。不知您在看了Kent Beck的文章之后有何感想,能否和InfoQ的读者们一同分享一下呢。
分享到:
相关推荐
目前就职于Facebook的极限编程创始人KentBeck在近期发表的一篇与别人合著的论文里向大家详细介绍了Facebook的开发与部署流程。 显而易见,Facebook的工程师们不会像传统软件行业那样使用瀑布模型进行开发,他们...
《测试驱动开发》是Kent Beck的经典著作,这本书深入探讨了测试驱动开发(TDD)这一软件开发实践。TDD是一种编程方法论,它强调在编写实际功能代码之前,先编写测试用例,以此来指导软件设计和编码过程。通过这种...
《测试驱动开发》是Kent Beck的经典著作,书名即为"Test-Driven Development by Example"。这本书深入浅出地介绍了测试驱动开发(Test-Driven Development,TDD)这一编程实践和技术,是理解并掌握TDD理念的重要参考...
学习如何编写高质量代码,如何提高代码的可读性,提升编程能力
测试驱动开发(Test-Driven Development, 简称TDD)是一种软件开发方法,由Kent Beck在其著作中提出。在TDD中,测试是开发过程的先驱,开发者首先编写测试用例,确保它们失败,然后编写最小化的代码来使这些测试通过...
测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,由Kent Beck在其著作《测试驱动开发:通过实例》中提出并详尽阐述。这种方法主张先编写自动化测试用例,然后再编写满足这些测试的代码,从而...
《测试驱动开发》(Test-Driven Development by Example)是由软件工程领域的大师Kent Beck所著的一本经典著作。该书主要介绍了测试驱动开发(TDD)的方法论,并通过具体的例子来展示如何有效地运用这一开发模式。本书...
### Smalltalk最佳实践模式——Kent Beck #### 一、引言与背景介绍 《Smalltalk最佳实践模式》是由著名的软件工程师Kent Beck所著的一本书,该书深入探讨了Smalltalk编程语言中的各种最佳实践和模式。Smalltalk是...
极限编程(Extreme Programming,简称XP)是由肯特·贝克(Kent Beck)和马丁·福勒(Martin Fowler)所提倡的一套敏捷软件开发方法论,它强调面对快速变化的需求,软件项目应能快速适应,保持高效的生产力和高质量...
《Smalltalk最佳实践模式》(Kent Beck)一书深入探讨了Smalltalk编程语言中的编码模式与最佳实践,为软件开发人员提供了宝贵的指导原则。以下是对该书内容的详细解析: ### 1. 软件品质与编程风格 - **Good ...
测试驱动开发(Test-Driven Development,简称TDD)是由著名软件工程师肯特·贝克(Kent Beck)在2003年提出的编程实践方法。这种方法主张先编写测试代码,然后编写满足这些测试的生产代码,以此来提升软件的质量...
测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,由Kent Beck在其同名著作《测试驱动开发》中提出。这种方法主张先编写测试用例,再编写实现功能的代码,以此来驱动开发过程,确保代码的质量...
"Test-Driven Development By Example"是一本由Kent Beck编著的经典著作,深入探讨了TDD的概念和实践。 TDD的核心原则包括: 1. **红灯原则**:首先,开发者编写一个失败的单元测试(因为此时还没有实现功能代码)...
XP的核心理念是将业务目标与软件开发紧密结合,通过一系列实践原则和流程来促进快速响应变化。 XP强调人与人之间的密切合作,认为开发人员之间的协作和与客户的沟通是成功的关键。它推崇团队中的项目经理、客户和...
测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,由肯特·贝克(Kent Beck)在2003年出版的《测试驱动开发:By Example》一书中提出并普及。这种方法强调先编写测试代码,再编写满足这些测试...
测试驱动开发(TDD),全称为Test-Driven Development,是由Kent Beck在其著作中提出的软件开发方法。这种方法强调在编写任何实际的代码之前,先编写能够失败的自动化测试。TDD的核心理念是“先写测试,再写代码”,它...
测试驱动的开发:通过示例(在Ruby中) 在阅读肯特·贝克(Kent Beck)的“测试驱动的开发:通过示例”(在Ruby中)的同时进行写作。 每次提交都意味着要运行测试套件。 有关每个提交消息的更多详细信息。 并在Wiki...
它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。 [1] JUnit是由 Erich ...
它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。[1] JUnit是由 Erich ...