天天看點

Facebook 是如何進行大規模代碼部署的

Facebook 高速發展的 2007 年到 2016 年,他們一天部署 3 次代碼,cherry-pick 集齊成千上萬個 commit;現在使用類似持續傳遞的方法,每個 commit 能自動部署到 production。公司裡有很多員工、很多使用者的好處:新代碼讓公司所有員工先用上,因為員工數足夠多,能很快發現問題;然後讓 2% 的通路量用上新代碼,最後慢慢增加到 100% 的通路量。

不久前有篇關于縮短 Facebook 釋出流程的文章,闡述了将代碼投入生産的靈活方法。這篇文章着重講述了他們在一年之内如何從“ cherry-picking ”更新到“ push-from-master ”政策。早些時候, Facebook 也分享了他們部署過程的細節。作者 Chuck Rossi 是 Facebook 的首位釋出工程師,目前是 Facebook 釋出工程的工程總監。

Facebook 的釋出周期是“ quasi-continuous ” (準連續)——這隻是一種委婉的說法,表明并非每次送出都會部署到生産環境,實際上它采用的是對幾十到幾百個送出進行批處理,每隔幾個小時就進行推送。這種分層釋出的方式使任何變更的復原很容易。

這個新系統從 2016 年 4 月開始,經過一年的時間慢慢地完善。早先的模式是從主幹分支的送出中選擇特定的變更放到釋出分支上。釋出分支每天将這些變更推送到生産環境。這種“ cherry-picking ”的特點是,每天選擇變更的數量為 500 ~ 1000。剩下的變更就推入到每周釋出分支中。随着時間的推移,送出的數量和參與其中的工程師都有所增加,釋出工程師的手工勞動變得過多,以至于無法持續。

這個 CD 系統的關鍵元件是一種控制方法,即誰将接收變更,以及用于部署和測量的自動化工具。在第一步中,經過一系列自動化測試後,變更就從内部推送到 Facebook 員工。在這一階段發現的任何回歸,都會被認為這一程序受阻或者停止。下一步涉及到“ canary deployment ”(金絲雀部署),隻推送至生産環境的 2% 。依靠連續的監測來檢測問題。如果一切順利,這些變更将 100% 部署到生産環境中。名為 Flytrap 的工具收集使用者報告,并發送任何異常情況的告警。

Facebook 中的 Web 和移動産品遵循兩條不同的路徑,原生移動變更的部署頻率低于 Web 。這兩個都由名為 Gatekeeper 的系統控制。除此之外,Gatekeeper 還分離出了部署和釋出。這種分離帶來了挑戰,包括維護向下相容性。

由于工具和部署選項的性質,移動持續部署面臨着一些特定的挑戰。Web 部署則更為容易,因為 Facebook 擁有完整的技術棧和工具。為了解決這些挑戰,Facebook 已經建構了一些專注于更快的移動開發的工具和庫,包括 Buck 、Phabricator、 Infer、 React 以及 Nuclide 。Facebook 的移動部署是以三層來并發運作。

• 建構:合并到移動主分支上的所有代碼都會進行建構,這會針對受影響的所有産品(Instagram、Messenger)并且會跨各種晶片架構。

• 靜态代碼分析:Linters 和靜态分析工具的組合,稱為 Infer ,用于檢查各種問題,包括資源洩漏、未使用的變量、有風險的系統調用和編碼準則違規。

• 自動測試:包括單元、內建和端到端測試,會使用到 Roboelectric、XCTest、JUnit 和 WebDriver 等工具。

在代碼變更的生命周期内,每次送出都會執行移動建構并運作測試棧,這樣就會運作很多次。單單 Android 一天就有 5 萬到 6 萬個建構版本。移動部署系統遵循較早的基于 Web 的模式,每周釋出一次,按 cherry-picking 政策随機選擇變更。盡管代碼傳輸速度和釋出頻率有所增長,但工程師的生産率保持不變。然而,本文提到的标準(代碼行和推送次數),可能并非衡量生産率的最佳标準。

據 2016 年 IEEE 的論文和相關讨論,Facebook 早在 2005 年就利用了某種形式的 CD。該論文中的一些結論列出了 CD 成功的先決條件:可觀的持續投資、高度熟練的開發人員、強大的技術管理,開放和平等的文化,風險回報權衡管理、客觀回顧失敗以及有專注力的小團隊。

Facebook 的準連續部署系統具備這幾個優點:沒有推送熱更新檔的手工開銷,對分布式工程師團隊有更好的支援,為工程師提供了更快的回報循環。

原文釋出時間:2017-10-31

繼續閱讀