不久前有篇關于縮短 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 的工具收集用戶報告,并發送任何異常情況的告警。
圖片來自:https://code.facebook.com/posts/270314900139291/rapid-release-at-massive-scale
Facebook 中的 Web 和移動產品遵循兩條不同的路徑,原生移動變更的部署頻率低于 Web 。這兩個都由名為 Gatekeeper 的系統控制。除此之外,Gatekeeper 還分離出了部署和發布。這種分離帶來了挑戰,包括維護向下兼容性。
構建:合并到移動主分支上的所有代碼都會進行構建,這會針對受影響的所有產品(Instagram、Messenger)并且會跨各種芯片架構。靜態代碼分析:Linters 和靜態分析工具的組合,稱為 Infer ,用于檢查各種問題,包括資源泄漏、未使用的變量、有風險的系統調用和編碼準則違規。自動測試:包括單元、集成和端到端測試,會使用到 Roboelectric、XCTest、JUnit 和 WebDriver 等工具。在代碼變更的生命周期內,每次提交都會執行移動構建并運行測試棧,這樣就會運行很多次。單單 Android 一天就有 5 萬到 6 萬個構建版本。移動部署系統遵循較早的基于 Web 的模式,每周發布一次,按 cherry-picking 策略隨機選擇變更。盡管代碼傳輸速度和發布頻率有所增長,但工程師的生產率保持不變。然而,本文提到的標準(代碼行和推送次數),可能并非衡量生產率的最佳標準。
據 2016 年 IEEE 的論文和相關討論,Facebook 早在 2005 年就利用了某種形式的 CD。該論文中的一些結論列出了 CD 成功的先決條件:可觀的持續投資、高度熟練的開發人員、強大的技術管理,開放和平等的文化,風險回報權衡管理、客觀回顧失敗以及有專注力的小團隊。
Facebook 的準連續部署系統具備這幾個優點:沒有推送熱補丁的手工開銷,對分布式工程師團隊有更好的支持,為工程師提供了更快的反饋循環。
查看英文原文:How Facebook Achieves Rapid Release at Massive Scale