【51CTO 4月12日外电头条】Facebook有一套成熟的软件交付流程,平均30分钟可完成一次升级。这套流程的背后有一个交付工程团队,以及一套BT部署系统。这个系统是如何运作的?Arstechnica网站去拜访了一次这个交付工程团队,揭开了这个系统的神秘面纱——
Facebook园区入口
Facebook总部设立于加利福尼亚州门洛帕克市,这同一片园区在多年前孕育出了Sun Microsystems这家同样声名在外的高科技企业。园区入口处矗立着巨大的宣传看板,相信每一位用过Facebook的朋友都不会对上面竖起大拇指的图案感到陌生——赞,这是用户表达肯定态度的方式,可能也标志着Facebook公司对自身成就的评价。我最近一次到园区采访的时候,恰好碰上一群十几岁的少年们聚集于此,争相在宣传板前合影留念。
一部席卷全球的热门影片“社交网络”让成千上万普通用户了解到Facebook公司如何从学生宿舍内的构想成长为世界第二大巨型网站,这样一个丑小鸭变天鹅的故事本身就极具传奇色彩。然而恐怕很少有人知道这家社交网站成功的背后,有多少技术人员在交付工作方面付出了艰辛的努力:先进的高科技基础设施造就了如今每天数以百万计用户的交互式Web应用体验,而这正是无数工程师呕心沥血打造出的傲人成果。
我前几天刚刚获准对Facebook总部进行专访,全程跟踪这家社交巨头的交付流程工作。Facebook公司正在筹备并部署一项全新社交功能,即“timeline”系统。而我则以独家观察者的身份参与到项目当中,随时收集第一手信息并将资料整理发布。
在Facebook园区入口与前往企业办公地点通路的交汇处,一个交通指标牌映入我的眼帘,上面写着:黑客之路。正如该公司创始人Mark Zuckerberg在今年早些时候的首次公开募股信中所言,他希望能以“黑客之路”的方式规划企业管理理念以及发展方向。在Facebook总部逗留的两天当中,我第一次与他们的交付工程师们共同生活、携手工作,并真正了解到黑客之路这一概念如何在该网站的成长与迅速普及当中起到决定性作用。
门洛帕克市的总部园区占地面积巨大,其间排布着密密麻麻的办公建筑;与其说是企业园区,这里倒更像是一个小型城市。建筑物当中随处可见精致的涂鸦式壁画及充满幽默气息的海报装饰。与传统的封闭或半封闭式办公环境不同,Facebook公司的开发人员一般会在大片开放式空间中进行工作,办公设备也沿着公用桌面排布,员工之间没有设置任何阻碍视线的隔挡。
每座办公建筑中都配备有公文室,在这里工作人员们可以在不干扰其他同事的前提下尽情开展讨论。有趣的是,每座建筑中的会议室都会以特定的主题命名。比如某栋楼里的会议室就是以“狂蟒之灾”这部电影中的一个笑话为名。另外,我还亲眼见到一些以电视节目命名的房间。而在工作人员的陪同下进入另一栋建筑时,我发现一间名为JavaScript:The Good Parts的房间。哈哈,这肯定是来自Doug Crockford所撰写的同名著作。
最终我来到交付工程团队的办公所在地。正如Facebook公司中的其它开发人员一样,交付工程师们同样使用开放式工作环境与公用办公桌。不过他们的房间仍然具有非常鲜明的特色:这里实际是一个酒水品种相当丰富的酒吧。
这个房间原本在两根垂直支撑柱之间设有一面背景墙。但在交付工程团队入驻之后,他们将这块区域改造成了酒吧吧台,并在台面上挑起他们精心挑选的名称:Hotfix(热修复补丁)吧。不用问,这个点子来自关键性软件补丁更新技术。而这里的员工就在围绕在吧台周围忙活手头的工作。
我正是在这里第一次见到交付工程团队的领导者Chuck Rossi。Rossi的工作设备就在吧台对面,这样他可以在工作的同时一伸手就抄起台面上的酒水饮料。我花了整个下午与这位曾效力于谷歌与IBM公司的资深软件开发人士谈天说地,这段时光非常美妙,真的像两个老朋友坐在科技气息浓郁的后现代酒吧中畅所欲言。正是以这种方式,我了解到Rossi如何带领他的团队帮助Facebook部署更新服务,并讨论这项工作的重要性及日常运作流程。
Chuck Rossi,Facebook交付工程团队的领导者,正坐在Hotfix吧旁接受采访
Facebook的BT部署系统
Facebook资源代码主要利用PHP编程语言进行编写。PHP语言在开发速度方面优势明显,但在性能方面比起低层次语言及某些现代编程替代方案却颇有不足。为了让这套以PHP为基础的基础设施在可扩展性领域更进一步,Facebook开发出了一套名为HipHop的特殊转译工具。
HipHop能够将PHP代码转译为高度优化过的C++代码,并通过二次编译将其转化为运行效率极高的本地二进制代码。Facebook于2010年正式推出HipHop并开始销售开源软件使用许可,同时该公司的工程师们指出,在HipHop的帮助下,Facebook业务流程中的CPU平均使用率瞬间降低了50%。
由于Facebook所使用的整套代码库都通过编译转化二进制可执行文件,因此该公司的整个部署流程与我们耳熟能详的PHP环境颇为不同。Rossi告诉我,Facebook所有应用程序的二进制代码库总体积约为1.5GB。当Facebook对代码进行升级并生成新的软件包时,新的全局代码库也必须同时被推送到企业内部的每一台服务器当中。
把1.5GB大小的二进制代码分配给不计其数的目标服务器,工作当中面临的技术挑战想想都令人头痛。在摸索出几套成型的解决方案之后,Facebook公司决定将BT技术敲定为最终手段。这种人气极高的点对点文件共享协议在向大量不同服务器传输大型文件方面拥有着不可替代的优势及上佳表现。
Rossi解释称,Facebook公司创建了自己的定制BT追踪工具,其设计目的是使Facebook基础设施中的每一台服务器都能够与同一节点或机架中的其它服务器一样获得相同的分区内容,如此一来总体延迟将得到大大降低。
目前Facebook网站升级的平均耗时为30分钟——其中15分钟用于生成二进制可执行文件,而另外15分钟则花费在通过BT体系将可执行文件传输至各Facebook服务器的过程中。
当然,二进制可执行文件只是Facebook应用程序堆栈中的组成部分之一。Facebook页面中还包含诸多调用自外部资源的项目,例如JavaScript、CSS以及图形要素等。这些文件被托管在分布于世界各地的内容交付网络(CDN)当中。
一般来说,Facebook会在每个工作日进行一次非关键性更新。而重大更新则每周进行一次,通常在周二下午进行内容发布。交付工程团队专门负责管理此类更新的具体部署工作,并全程跟踪以确保更新的顺利完成。
频繁的更新及发布是Facebook在创立之初就确定下来的核心发展理念之一。在该公司刚刚迈入起步阶段的时候,开发人员利用快速迭代及增量工程手段坚持不懈地对网站加以完善。这种技术层面上的灵活性在Facebook的发展及演变当中起到了关键性作用,并成功让这家年轻的企业迅速成长为举世瞩目的社交巨子。
当初Facebook公司招募Rossi的时候,是希望他能够领导交付工程团队找到合适的途径,确保企业在快速发展的同时步伐稳健、基础牢固。对于正处于急速扩张当中的Facebook而言,其网站的规模与管理复杂性也在以几何级数式增长。要实现牢固稳妥的交付战略,传统的解决方案已经无法满足需求。正是在这时,他们想到了BT部署系统。
在与Rossi共同度过的那个愉快的下午,我在概念上基本理解了他解决Facebook部署问题的处理方式。总结起来,他希望能在客观条件与理论目标之间找到一个平衡点。他制定了一套相当严格的质量及稳定性标准要求,但具体到解决方案层面却将着眼点放在高灵活性上。资源总是有限的,他认为最好的办法是通过系统灵活性来应对各种意想不到的麻烦。
测试工作
在最近的几篇文章中,我们已经与读者朋友深入探讨了软件应用程序步入高速交付周期所带来的挑战与机遇。而挑战当中最难以克服的一个就是,如何在测试时间远低于原先水平的前提下保证软件的质量不打折扣。
由于Facebook网站每天都会进行更新,因此质量测试也就成了压力最大、负荷最强的先锋部门。为了快速发现问题,Facebook中每一位通过企业内部网络访问该社交网站的员工,都将直接登入采用了最新代码的实验性网站架构。在这里他们能够接触到一切尚未经过测试的修改建议以及还没有在正式网站上采用的最新功能。与此同时,员工还可以通过另一个单独的网址访问与外界用户相同的正式运行版网站,这样两相对比之下可能更容易发现问题。
将测试网站设定为企业员工的默认访问对象,能够在新元素及功能付诸实践之前先经受专业人士的检测。测试网站中还包含了一些内置的错误报告工具,员工一旦发现问题,就可以利用它们轻松提供详细反馈。
为了避免回档事故并确定通用性技术问题,Facebook还部署了一套自动测试系统。该公司将这类测试分为两个独立的部分:一部分专门进行代码的常规完整性测试,而另一部分则模拟用户的日常使用情境,以确保网站的用户界面能够运转良好。
在更新全面付诸实践之前,新的代码将首先被推送到“a2”层,也就是由数台Facebook公共服务器组成的试点环境。在这个阶段的测试工作中,会有一些随机Facebook参与到更新中来。尽管参与者的数量在Facebook全局用户群体中只占极小的比例,但技术人员仍然能从整个更新流程中发现潜在问题并及时加以修复。
Chuck Rossi和他的工作台
预检流程
Facebook利用自己的内部多人在线聊天系统(IRC)服务器保持企业中的交流通畅。大多数企业的工程人员在工作强度较大时,交流通道都显得比较冷清。但根据Rossi的说法,Facebook公司在正常运作状态下,每天会有约700名员工保持在线沟通。工具开发人员专门为IRC打造了几种业务助手软件,能够将IRC中的各类功能与Facebook开发与部署工作流程紧密结合,进而发挥巨大的辅助作用。
在新一轮升级补丁即将上线之前,Rossi会在IRC系统中启动一套检测程序。在此次更新活动中提交过代码的开发人员都将收到通知,并加入频道以共同关注更新过程。整从此更新流程将在大家的协同监控之下试作一次,当确认一切正常后才会进入实际部署阶段。
如果某位开发人员在几分钟之后仍然没有做出协作回应,Rossi能够利用助手通过多种不同的通讯渠道对该开发人员发出提醒,其中包括电子邮件通知以及短信提示。正如Rossi在与我的交谈中所强调的,他希望部署更新的时候所有与之相关的开发人员都能在场监督并发表意见。
在Facebook公司内部存在着这样一种优秀的开发文化,大家都认为开发人员应该为自己编写的代码负责到底,直到这些成果顺利应用于产品之中。这一理念的实际体现就是“DevOps”活动,这种促进开发、技术运营及质量保障部门间沟通的方案有效消除了各团队之间的沟通障碍,并最终保证了项目的成功运转。
如果Facebook网站在实际更新过程中出现问题,编写相关代码的开发人员会立即得到提示,并马上投入到修复工作中去。
实际部署
Rossi在Facebook公司中的工作台由以下设备构成:一台30英寸戴尔显示器、一台Mac笔记本电脑以及一台分屏显示器。上周二,我花了一整天时间观察Rossi的日常工作内容,发现他的大部分工作都是在浏览器以及终端窗口中完成的。在准备部署更新之前,他在终端窗口发出指令,正式启动本次升级流程。
我们一同关注着Facebook网络系统监控工具所显示出的各项状态指标。网页的主体内容是个大大的进度条,标明企业内部已经成功完成二进制文件更新的服务器所占的百分比。随着更新的自动部署,进度条也在不断向终点推进。过程中,进度条左端出现了窄窄的红色提示条,意味着新版本在更新时发生错误的系统比例。
Rossi告诉我,这种系统更新失败的情况经常发生。在部署过程中,升级失败往往是由硬件问题所引发。举例来说,如果某台服务器的存储容易不足或者运行种子文件时遭遇网络问题,那么更新很可能无法完成。不过出错的服务器数量一般都很小,只需简单调整即可恢复正常,几乎不会惹出什么大麻烦。
尽管软件的部署对象是服务器,但Rossi告诉我Facebook的架构仍然会对更新过程产生一些独特的影响。Facebook在设计之初要求用户会话能够不依赖于任何特定的服务器设备,以分布式程度极高的无地区差形式进行运作。也就是说,Facebook基础设施中的任意一台服务器都能够处理任何给定的页面操作请求。
这种方式为全局系统提供了异乎寻常的弹性。当Facebook执行更新时,工作人员不必担心用户会话的状态会受到干扰或进行迁移。部署系统会在服务器端分批对Facebook执行流程加以重启,这样一来整个更新过程就能够以无缝化形式进行。无论是已经完成更新的还是仍然运行着旧版本系统的服务器,都能够继续处理接收到的用户页面请求,而与此同时企业基础设施的全面更新也在有条不紊地进行当中。
Facebook在更新与正常业务同时运转的情况下,系统设施将几乎处于满负荷状态。通常情况下,Facebook典型更新在部署中不需要预设停机时间,也绝不会引发任何形式的网站服务中断现象。Rossi指出,无停机更新流程是Facebook交付工作策略中的一项原则性要求。他为此感到自豪,并认为这是对网络软件工程工作优秀与否的一种检验。
事后检查
更新流程彻底结束之后,Rossi还需要做进一步审查,以确保系统变更没有对任何层面的原有内容造成破坏。他的团队为此专门打造了一套先进的分析工具,其作用是追踪Facebook网站的各项运行状态。工具的主仪表板上的线形图显示出各检测指标的变化情况,包括流量、资源消耗、产品独立组件故障率以及其它各种重要数据。
关注这些系统状态的浮动与走势,能够有效帮助工程人员辨别并修正系统中出现的问题。在故障发生之初,技术人员能够快速将当前数据与历史记录进行比照,并轻松准确地查明问题出在哪里。交付工程团队及其它Facebook工程小组会在更新结束后继续严密留意网站的运行状态,以确保一切项目及功能仍然运转良好。
一旦发现问题,例如系统中的某部分出现不合理的高故障率,那么企业中的工程师们将立即开始对错误日志进行深入分析,以找出问题发生的根源。Facebook所使用的内部工具非常犀利,在它的帮助下技术人员可以很轻松地观察并分析日志内容,并将结论与代码变更及特定错误提示相结合,最终拿出一套最为简洁高效的修复方案。
Facebook所使用的内部监控工具能够追踪大量数据源,甚至连与Facebook相关的tweet消息也涵盖在内。通过收集与汇总,该工具将分析结果以单独的走势曲线图进行表示,直观展现了网络用户对Facebook正面与负面评价的所占比例及变化。这一点非常重要,因为当我们在某种社交网络中遭遇技术缺陷或应用故障后,很可能会在其它网站上大肆抱怨以发泄怒气。对这类内容保持关注,就能帮助Facebook的技术人员迅速掌握那些可能被自己忽略掉的系统故障。
根据我的观察,当天的更新流程非常顺畅,没有出现任何技术问题或系统故障。日志消息的图表中曾经显示某个系统组件出现了小小的负载高峰,但通过Rossi及其团队的及时追踪及排查后,发现一切都属于正常现象。
Facebook公司交付工程团队在庆祝“一周一度“的更新成功
回档是失败者的行为
尽管在我的采访过程中并没有出现什么乱子,但Rossi还是非常热心地满足了我的好奇心。这个问题其实也一直在困扰着我:一旦更新过程发生故障,Facebook会怎样处理?他的回答是,如果在更新结束后有一大堆错误暴露出来,交付工程团队将与相关开发人员通力合作,力争在最短的时间内解决这一问题。当修复方案准备就绪,Rossi的团队将立即将其投付部署,并组织新一轮更新。
当某些错误太过严重时,快速修复几乎是不可能完成的任务。因此我问他此前有没有将网站恢复到旧有版本的经历。但他的回应斩钉截铁:“回档是失败者的行为!“
不过他又微笑着补充道,事实上他确实也执行过系统回档。Facebook拥有一套合理的机制,能够快速高效地将系统恢复到上一个版本,但他们只将此作为最后一项保障性手段使用。每台服务器中都保存着上一个版本的二进制文件,并能够在绝对必要的情况下立刻进行切换。
他告诉我,对于Facebook这样的大型社交网站而言,进行系统回档就像拉下火车上的紧急刹车一样;这么做并不可取,因此除非别无选择,否则他们绝对不会尝试。在他就职于Facebook的数年中,系统回档的情况也只碰上过几次。
Facebook的测试机制以及开发人员问责理念有效防止了代码编写工作中出现严重错误的机率。当开发人员的代码破坏了网站架构时,他们不仅需要立即投入修复工作,还必须承担绩效评估及人事变动等层面的惩罚。Facebook公司中的代码归属与开发人员紧密相联,因此根本不用指望在捅出娄子之后仍然高枕无忧。
该公司所使用的内部工具具备一种标志性的Facebook式灵感,而Rossi也对这种评估机制赞不绝口。这是一种评分工具,它赋予了Facebook公司中每位员工一定的“karma”值,这一佛教用语通俗一点来说可以看作是“善恶值”。善恶值与代码审查系统直接挂钩,每位开发人员在网页仪表板中都拥有自己的状态栏,Rossi可以通过点击栏中的“顶”或“踩”图标来提升或降低对应员工的善恶值属性。
在Rossi的工具中,表示“顶”的功能图标与Facebook社交网站中的那个完全一致。而表示“踩”的图标则正好是把“顶”的图形上下倒置。Rossi不无得意地向我展示了他的图标,并开玩笑说他是世界上惟一一个能使用Facebook式“踩”图标的家伙。
善恶值的设定能够帮助Facebook公司时刻掌握员工的工作状态,不过在代码审查过程中,评分机制同样能够帮上大忙。在对更新代码进行整体整合时,Rossi能够一目了然地发现哪些代码是由“善恶值”较低的技术人员所编写,这样他就会对这些代码格外关注,因为这帮家伙出错的潜在风险更高。
善恶值较低的员工可以通过自身的良好表现及工作态度逐渐提升这项评分——不过也有些人冥顽不灵,他们居然打算通过给Rossi带小点心的方式让他放自己一马。不过最令人惊讶的是,Rossi真的认同了这一做法。他告诉我,酒和蛋糕是员工恢复善恶值的首选礼品。说到这里,他又指了指交付工程团队办公室中那令人印象深刻的酒水储备:其中很大一部分就来自犯了错的开发人员。
Facebook公司交付工程部门中的Hotfix吧——以酒补过,原来这才是hotfix的真正含义
发展前景
我与Rossi探讨了他对于发展前景,尤其是Facebook的部署策略在企业技术基础设施发生变化之后的预期走势。他认为,随着时间的推移,他的团队在工作效率方面将进一步提高:准备过程、构建工作以及部署耗时等项目都还有潜力可挖,到时候整套更新任务可能几分钟就能搞定。
目前Facebook最重视的开发工作之一是推出一个能够取代HipHop转译器的新型后备项目。Facebook公司的开发人员正在创建自己独有的字节码格式及自定义运行环境,他们将其称为HipHop虚拟机,并希望它能成为支持Facebook运行的下一代平台。这一项目完成之后,该企业将能够把PHP源代码编译成能够为虚拟机直接运行的字节码。
如此一来,托管代码模式将更接近于Java及.NET,这样的进展能够让Facebook在保证代码一致性的前提下进一步提高系统灵活性。抛开其它各类优势不谈,Rossi告诉我这种态势将对现有部署流程产生重大影响。过去每一次更新都必须在所有服务器上传输1.5GB体积的二进制代码库,而未来他们只将与修改内容相关的字节码发出即可完成更新。Facebook网站甚至有能力将更新字节码与正处于运行状态的应用程序直接拼接,这样连进程都不必重新启动了。
一旦上述理想能够成为现实,整个大规模更新流程将能够在数分钟内完成,而Facebook也就可以借此彻底抛弃以往的更新时间表,真正按照开发思路将增量部署纳入变更模式之中。在这种情况下,企业开发人员则获得史无前例的高度敏捷性。
在周二例行的关键性更新结束之后,Rossi和他的团队开始对系统加以分析,以确保更新工作没有引发任何问题。当一切圆满结束之后,他们在hotfix吧举杯畅饮以示庆祝。
欢乐的时光总是过得特别快,在结束了一天的采访、再次漫步在Facebook园区的黑客之路上时,我不仅慨叹默默无闻的“交付工程团队”在扶持Facebook顺利发展的道路上起到了如此巨大的作用。
Facebook尽心竭力所打造出的社交平台,让我们每一位普通使用者得以在其中分享过往阅历、记录当年点滴,这不禁令人心生景仰。而在这喧闹繁华的平台背后,却有着这样一群从未出现在灯光下的技术人员。他们拥有强大的知识背景,创造着与大多数人不一样的奋斗故事。希望大家记得,正是由于这些个性鲜明、可敬可爱的人们的存在,Facebook才能始终光辉耀眼、独领风骚。
原文:Exclusive: a behind-the-scenes look at Facebook release engineering