search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

谷歌是如何構建 Web 框架的

作者|麥克周編輯|江柳

根據谷歌對外公布的數據,它的 20 億行代碼都部署在同一個代碼倉庫里,通過基於基線的方式進行開發工作中的代碼共享。

從上面這張圖可以看到,一共有文件 10 億個,源文件數量達到 900 萬個,源代碼行數達到 20 億行,提交代碼的深度可以挖掘到 3500 萬次提交,平均每個工作日提交 4 萬次,數字真是恐怖。

從大眾的眼光來看,特別是那些谷歌公司外部的人,他們會覺得這種單一代碼倉庫的管理方式,尤其是代碼量這麼恐怖的前提下,這種管理方式很不正常,但是它真的很有效,而這種有效是由管理方式決定的,而不是單純讓它自然生長。

Rachel Potvin 和 Josh Levenberg 編寫的一篇文章里是這麼描述的:

谷歌的代碼庫由全球數十個辦公的超過 2.5 萬名軟體開發工程師所共享,平均每天他們會提交 1.6 萬次代碼修改請求。

只有一個版本

正如下面這張圖所顯示的,在谷歌,你看不到代碼分支,拉代碼分支是很多公司的習慣做法,在開發階段這個很方便,相當於一個個獨立的 Docker 鏡像,但是等代碼合併的時候就不是這麼好玩了。

對於只有一個源碼倉庫的開發模式來說,你不可能出現應用程序 FooBar 使用 AngularDartV2.2.1 版本,而另一個應用程序 BarFoo 使用 2.3.0 版本的情況。兩個應用程序必定需要使用同一個版本。這其實是將多版本之間的完全兼容性測試由出現問題轉移到了代碼提交環節。

每次提交 74000 個測試用例

我們這裡以 AngularDart 框架為例,它目前有 1601 個測試用例。當你向谷歌的代碼庫提交一次 AngularDart 代碼時,會自動為所有依賴於 AngularDart 框架的工程運行測試用例。也就是說,差不多有 74000 個測試用例(視依賴的工程數量而定,這裡只是舉一個例子,有些流行的框架可能測試用例會更多)。

我們舉個例子,也許你修改代碼的數量很少,例如「&& random.nextDouble > .05」,你只是增加了這麼一個判斷條件,它並沒有觸發 1601 個測試用例裡面的任何一條,但是因為你增加了這個判斷,它可能會對框架的使用方造成問題。

真正的價值在於,提交代碼時所作的測試時針對真實的應用程序的。不僅僅測試的量級很大,針對使用方的測試也可以反應你的框架是如何被開發者所使用的。這就好比我們自己寫框架的人,寫出來的測試用例都是符合我們思考方式的,但是你無法左右你的客戶如何使用你。

對於生產環境下的應用程序,我們應該明白它們和測試環境的示常式序存在巨大的區別,你當前支撐得好,他們才會一直使用下去,這種做法也是為了更好地支持後續的開發活動。

你製造麻煩,你修復它

正如標題所說,如果 AngularDart 的作者引入了一個改變,哪怕只是一行代碼的改變,他們都需要直接去為客戶解決問題。也正是由於谷歌只有一個代碼庫,所以 AngularDart 作者可以直接修復問題。

所有的修改代碼和針對客戶的修復措施代碼,它們都需要同時被提交帶代碼庫,當然,還需要所有相關方的代碼評審完成之後才能提交。

我們舉個例子。當 AugularDart 團隊的成員想要做代碼修改,而這次的代碼修改會影響 AdWords 這個應用程序的代碼,那麼 AugularDart 團隊的成員需要直接進入 AdWords 的源代碼,然後修復問題。他們可以運行 AdWords 已存在的測試用例,也可以自己增加一些新的用例。然後他們把所有的改變寫入改變列表(change list)並提交評審。因為他們的 change list 涉及到框架(AngularDart)和調用方(AdWords)的代碼,所以系統會自動請求來自雙方面的成員進行代碼代碼審核和批准請求。

當然,業界也有其他的批評,認為 AngularDart 開發者僅關注了谷歌內部的使用方,例如 AdWords,而沒有關注外部的使用方,例如 Workivas、Wrikes,以及 StableKernels。

大規模改變

如果 AngularDart 準備進行一次大規模的改變,例如從 2.x 升級到 3.0,是否真的需要為所有的使用者(框架依賴方)修復缺陷、運行測試用例,答案是:Yes。

當類 Foo 里的一個方法從 bar 變為 baz,你可以構建一個工具,這個工具可以遍歷整個 Google 代碼庫,自動搜索所有的 Foo 類及其子類的實例,直接把它們修改為 baz。

性能指標

除了關注功能,谷歌還要求框架提供方關注提交代碼后出現的性能問題。谷歌會自動為每一個使用方生成性能測試結果,這個性能測試是針對生產環境的,絕對真實。

Hermetic 構建工具

對於大量的測試用例,開發人員當然不可能一個一個去運行,一個個修復缺陷,他們使用的是 Bazel(開源構建代碼工具)。在這個量級下你不可能使用一系列的 shell 腳本構建工程,你需要的是 hermetic 構建工具。

hermetic 在這裡的意思有點類似於「純正」,你構建的步驟不能有單邊影響(例如 temo files、changes to PATH 這些修改),修改需要是可以判斷的(例如輸入什麼導致輸入改變)。你可以在自己的機器上通過 hermetic 工具先運行測試用例,相當於你機器上的客戶端,運行通過後把改變代碼提交到伺服器上并行構建它們。

總結

通過這種類似於提供方作為責任方的制度,讓谷歌的軟體開發人員對於每一行代碼的提交都會非常謹慎,但是也對生產環境的程序穩定性、性能提供了充分的保障,此外,通過這種方式也會影響開發人員對於產品的開發思維,讓他們可以站在用戶的立場上思考如何更好地構建自己的框架,這其實也是在一定程度上推動技術和產品的發展。

細說雲計算

「細說雲計算」是InfoQ旗下關注云計算技術的垂直社群,投稿請發郵件到[email protected],註明「細說雲計算投稿」即可。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦