Monorepo與multirepo區別何在?為什么大公司像谷歌.微軟.優步.Neflix.Nike都在Monorepo?
Monorepo是一個新的名詞,但不是一個新的概念。從軟件開發最開始,我們已經在開始用這種模式了。這種模式的一個中心思想就是,用一個repo來管理所有的源代碼。除了這種模式以外,另一個比較受推崇的模式就是multirepo,也就是用多個repo來管理自己的源代碼。
不需要深刻思考這兩種模式,各有利弊。今天我們來分別說一下這兩種模式,但會著重來講使用Monorepo可能會遇到的問題。
現在比較大型的軟件開發公司,比如說Google, Uber, Netflix他們都在使用monorepo。但是對于我們中小型公司或者個人開發者來說,到底需不需要用monorepo,還是選擇multirepo?
好,我們就現在具體談一下monorepo。在這種模式下,你所有的設計文檔,所有的源代碼,所有的所有都放在一個repo里面。這樣做的好處有這些:?
你的一次提交可以解決所有的問題。
這個提交可以是添加一個功能,修改一個bug,這個功能添加或者代碼修改會涉及很多不同的模塊兒,這些模塊都可以在一個change request里面做完。
因為所有的這些修改都在一個repo里面,這樣你查找歷史,查看這些修改之間的關聯都比較容易。
當然了,這個好處的獲取需要所有的程序員和文檔提交者都遵循一個統一的格式。
另一個好處,是所有的人都有訪問權限。這樣就杜絕了權限申請方面的種種問題。不存在這些代碼,某些人看不了的問題。整個開發團隊里面沒有任何秘密。
好,上面說了monorepo的好處, 那為什么現在很多人都在用multirepo呢?
現在就來說說monorepo的壞處。
Monorepo, 一個最大的問題就是隨著程序規模的不斷增加,代碼量的增加,文檔的增加,整個repo會變得越來越大。
我以前做過一個Nike的項目, 那個項目使用的就是monorepo的模式。那個repo當時的大小是21g。怎么樣?你的小心肝還能承受得住吧?
試想一下,一個程序員只想改一下其中的一個翻譯文字,你就需要把這21G大小的整個repo都拿到你的本地來。這個過程一定是欲仙欲死的。現在使用multirepo的人一定會對你說good luck。
另一個壞處也是上面說的好處,就是權限訪問的問題。Monorepo模式下的權限是開放的。代碼安全,文檔安全,都會是一個需要好好考慮的問題。
這個方面如果處理不好的話,對整個團隊整個項目帶來的后果可能是災難性的。
像google這樣的大公司他們都用自己的代碼管理系統,那一個程序員要修改一個模塊的代碼的時候,他需要把所有的項目代碼都下載到本地來,并獲取最新的代碼。做一個修改以后,check in完成就會進行整個項目的編譯。整個項目可能需要兩個小時的編譯時間,這個時候,這個程序員可以跟別人聊聊天,可以學點東西,這也是很好的一種程序員生活。在monorepo的開發模式下,這是一個非常常見的工作狀態。
為了對這些修改做好標志,每一次一些標志性的修改都會添加一個版本號。對應一個版本號都會有一個版本歷史。對應每個版本號又會有一個對應的標簽。大部分時間我們只對最新的版本感興趣。
接下來我們來看一下multirepo, 在這種模式下,你很少見到一個非常龐大的代碼庫或者文檔庫。但這不能說這種模式,就是完美的。它還會有別的其他的問題。
這種模式的總的設計是一個把一個大的問題分成幾個小的問題來解決。通過問題的細化,減少整個問題解決的復雜度,從而讓自己的工作更加順手,更加有保障。
上面這個設計是不是聽起來很熟悉,對了, 它跟微服務架構是一個理念。
通過這個分解,每一個小部分作為一個單獨的repo。每個repo,可以分給不同的小組來開發和管理。每個小組只需要關心這一小部分工作就可以了。每一個小的部分都可以單獨的進行測試和開發。這個是好的一個方面。
下面來說一個壞的方面。因為每個小組可以各自為戰。這樣就給協同工作帶來很大的問題。比如說一個小組的模塊進行了升級,導致現有的大系統其他模塊兒無法正常工作。這種現象在微服務架構系統的開發中非常常見。
如果把這個壞的方面再發揮到極致,就是每個組件之間互相依賴互相破壞,這樣子你整體系統可能就陷入萬劫不復的深淵。也就是說,隨著微服務架構,繼續把模塊兒進細化,每個模塊失去了緊密的聯系,與此同時又沒有很好的管理機制把握全局, 導致整個項目開發失去了控制,這也是很多微服務架構系統失敗的原因。
所以在multirepo的開發過程中,非常重要的一點就是避免過度的細分。一定要有一個機制來把握全局,時刻監控整個開發環境是否正常。
制定標準是一個很有意思的話題, 雖然說技術上很難爭高下, 但是總會辯論出一個最好的方案來,但是最嚴重的有時候根本不是技術上的問題。這個里面就會有很多說不清道不明的問題了。
就因為如此,在一些大公司當中,因為人員的素質都比較高,都是高手,常言說一山不容二虎,這里山中有好幾只,幾十只老虎。在這種情況下,用一只老虎的標準來把握全局是很難的。
所以寧愿犧牲一些下載時間,編譯時間上的代價,最終他們還是繼續使用monorepo的模式。
還有一個在multirepo中不可忽視的一個問題就是為了保證一個功能的完整運行, 即使再小的改動,也有可能對所有的repo進行更新。這是一個非常煩人的過程。
我工作過的一個multirepo項目,它里面有20多個模塊。要想使整個系統工作完整,你需要把這20多個模塊都下載到本地來,當然,你可以采用一些比較簡潔的方式,比如說docker container的image, 盡可能的減少與過多的模塊兒直接的接觸。在這種模式模式下我相信你是非常喜歡黑盒模式的。因為模塊太多,你根本不想搞清楚它里面到底在干什么。只要能給你工作就行了。一個是太煩人,另外一個是時間太緊張了。
那么現在的問題就是,上面兩種模式哪種更好呢?我的觀點是,不管你喜歡哪種模式,選擇哪種模式,他們都是你的工具,你要控制他們,而不是他們控制你。
這種模式的本意都是想讓你的工作做得更好。
Monorepo你需要做的是盡可能的把你的測試案例細分開。這樣你在提交一個修改的時候,就不需要把所有的測試都過一遍,那樣太費時間了。
Multirepo對于你自身模塊的測試案例,你需要做的是把與你的模塊相關的測試案例都放進來。在你提交一個修改的時候,要保證所有的這些案特殊案例都通過。如果需要下載相關模塊的修改更新,要盡快通知大家去下載。
一個很常用的模式是這兩種模式的結合。你比如說一個修改,你可能需要修改很多個repo, 那你可以考慮把這多個repo合成一個。
關于這個話題還有很多要可以談的,我們這一期就先談這些吧。
這里是丁哥開講,歡迎關注防止失聯。