谷歌是如何構建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()。
GIF/466K
性能指標
除了關注功能,谷歌還要求框架提供方關注提交代碼後出現的性能問題。谷歌會自動為每一個使用方生成性能測試結果,這個性能測試是針對生產環境的,絕對真實。
Hermetic構建工具
對於大量的測試用例,開發人員當然不可能一個一個去運行,一個個修復缺陷,他們使用的是Bazel(開源構建代碼工具)。在這個量級下你不可能使用一系列的shell腳本構建工程,你需要的是hermetic構建工具。
hermetic在這裡的意思有點類似於「純正」,你構建的步驟不能有單邊影響(例如temo files、changes to PATH這些修改),修改需要是可以判斷的(例如輸入什麼導致輸入改變)。
你可以在自己的機器上通過hermetic工具先運行測試用例,相當於你機器上的客戶端,運行通過後把改變代碼提交到伺服器上並構建它們。
總結
通過這種類似於提供方作為責任方的制度,讓谷歌的軟體開發人員對於每一行代碼的提交都會非常謹慎,但是也對生產環境的程序穩定性、性能提供了充分的保障。
此外,通過這種方式也會影響開發人員對於產品的開發思維,讓他們可以站在用戶的立場上思考如何更好地構建自己的框架,這其實也是在一定程度上推動技術和產品的發展。
點擊展開全文
※「吃青春飯」的程序員們:再過 5 年,你還在寫代碼嗎?
※PHP 的數據結構擴展
※Node.js 性能調優之代碼篇(一)——使用原生模塊
※他們都說學習互聯網技術不重要,可憐的是你深信不疑
※五款輕量級的web前端框架和H5前端框架的點評
TAG:優才學院 |
※使用 Python 和 Pygame 模塊構建一個遊戲框架
※如何看IBM 構建的Modern架構中,存儲角色越來越重要?
※Facebook 開源 PyText:用於構建自然語言系統的框架
※無需深度學習框架,如何從零開始用Python構建神經網路
※使用 Scrapy 構建一個網路爬蟲
※構建非同步伺服器和客戶端的 Kotlin 框架 Ktor
※如何為本地SEO創建kickass鏈接構建策略
※Snapchat 的野心:構建以 AR 為基礎的計算平台
※Power BI 構建基塊
※K8S 分散式構建 Docker 鏡像的一些小技巧
※如何基於 Flink 構建高可用的實時計算平台?
※「像造iPhone一樣造木結構建築」!聽聽Katerra首席工程師怎麼說
※我們是如何使用 Electron 構建 Linux 桌面應用程序的
※使用 Ansible 在樹莓派上構建一個基於 Linux 的高性能計算系統
※Dweb:使用WebRTC/WebTorrent構建彈性Web
※Aeternity-構建真正的去中心化區塊鏈?
※AltspaceVR支持在虛擬現實中構建可共享空間
※用Pytorch構建一個自動解碼器
※如何快速構建一個 Spring Boot 工程?
※如何在Kubernetes構建資料庫服務?