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的讀者們一同分享一下呢。
原文轉自:http://www.infoq.com/cn/news/2013/10/facebook-development-deployment