Monorepo與multirepo區(qū)別何在厢岂?為什么大公司像谷歌.微軟.優(yōu)步.Neflix.Nike都在Monorepo?
Monorepo是一個(gè)新的名詞,但不是一個(gè)新的概念焕蹄。從軟件開發(fā)最開始,我們已經(jīng)在開始用這種模式了阀溶。這種模式的一個(gè)中心思想就是腻脏,用一個(gè)repo來管理所有的源代碼。除了這種模式以外银锻,另一個(gè)比較受推崇的模式就是multirepo,也就是用多個(gè)repo來管理自己的源代碼迹卢。
不需要深刻思考這兩種模式,各有利弊徒仓。今天我們來分別說一下這兩種模式,但會(huì)著重來講使用Monorepo可能會(huì)遇到的問題腐碱。
現(xiàn)在比較大型的軟件開發(fā)公司,比如說Google, Uber, Netflix他們都在使用monorepo。但是對(duì)于我們中小型公司或者個(gè)人開發(fā)者來說症见,到底需不需要用monorepo,還是選擇multirepo?
好喂走,我們就現(xiàn)在具體談一下monorepo。在這種模式下谋作,你所有的設(shè)計(jì)文檔芋肠,所有的源代碼,所有的所有都放在一個(gè)repo里面遵蚜。這樣做的好處有這些:?
你的一次提交可以解決所有的問題帖池。
這個(gè)提交可以是添加一個(gè)功能,修改一個(gè)bug吭净,這個(gè)功能添加或者代碼修改會(huì)涉及很多不同的模塊兒睡汹,這些模塊都可以在一個(gè)change request里面做完。
因?yàn)樗械倪@些修改都在一個(gè)repo里面寂殉,這樣你查找歷史囚巴,查看這些修改之間的關(guān)聯(lián)都比較容易。
當(dāng)然了友扰,這個(gè)好處的獲取需要所有的程序員和文檔提交者都遵循一個(gè)統(tǒng)一的格式彤叉。
另一個(gè)好處,是所有的人都有訪問權(quán)限村怪。這樣就杜絕了權(quán)限申請(qǐng)方面的種種問題秽浇。不存在這些代碼,某些人看不了的問題甚负。整個(gè)開發(fā)團(tuán)隊(duì)里面沒有任何秘密兼呵。
好,上面說了monorepo的好處, 那為什么現(xiàn)在很多人都在用multirepo呢?
現(xiàn)在就來說說monorepo的壞處腊敲。
Monorepo, 一個(gè)最大的問題就是隨著程序規(guī)模的不斷增加击喂,代碼量的增加,文檔的增加碰辅,整個(gè)repo會(huì)變得越來越大懂昂。
我以前做過一個(gè)Nike的項(xiàng)目, 那個(gè)項(xiàng)目使用的就是monorepo的模式。那個(gè)repo當(dāng)時(shí)的大小是21g没宾。怎么樣凌彬?你的小心肝還能承受得住吧?
試想一下循衰,一個(gè)程序員只想改一下其中的一個(gè)翻譯文字铲敛,你就需要把這21G大小的整個(gè)repo都拿到你的本地來。這個(gè)過程一定是欲仙欲死的』岫郏現(xiàn)在使用multirepo的人一定會(huì)對(duì)你說good luck伐蒋。
另一個(gè)壞處也是上面說的好處工三,就是權(quán)限訪問的問題。Monorepo模式下的權(quán)限是開放的先鱼。代碼安全俭正,文檔安全,都會(huì)是一個(gè)需要好好考慮的問題焙畔。
這個(gè)方面如果處理不好的話掸读,對(duì)整個(gè)團(tuán)隊(duì)整個(gè)項(xiàng)目帶來的后果可能是災(zāi)難性的。
像google這樣的大公司他們都用自己的代碼管理系統(tǒng)宏多,那一個(gè)程序員要修改一個(gè)模塊的代碼的時(shí)候儿惫,他需要把所有的項(xiàng)目代碼都下載到本地來,并獲取最新的代碼伸但。做一個(gè)修改以后肾请,check in完成就會(huì)進(jìn)行整個(gè)項(xiàng)目的編譯。整個(gè)項(xiàng)目可能需要兩個(gè)小時(shí)的編譯時(shí)間砌烁,這個(gè)時(shí)候,這個(gè)程序員可以跟別人聊聊天催式,可以學(xué)點(diǎn)東西函喉,這也是很好的一種程序員生活。在monorepo的開發(fā)模式下荣月,這是一個(gè)非常常見的工作狀態(tài)管呵。
為了對(duì)這些修改做好標(biāo)志,每一次一些標(biāo)志性的修改都會(huì)添加一個(gè)版本號(hào)哺窄。對(duì)應(yīng)一個(gè)版本號(hào)都會(huì)有一個(gè)版本歷史捐下。對(duì)應(yīng)每個(gè)版本號(hào)又會(huì)有一個(gè)對(duì)應(yīng)的標(biāo)簽。大部分時(shí)間我們只對(duì)最新的版本感興趣萌业。
接下來我們來看一下multirepo, 在這種模式下坷襟,你很少見到一個(gè)非常龐大的代碼庫或者文檔庫。但這不能說這種模式生年,就是完美的婴程。它還會(huì)有別的其他的問題。
這種模式的總的設(shè)計(jì)是一個(gè)把一個(gè)大的問題分成幾個(gè)小的問題來解決抱婉。通過問題的細(xì)化档叔,減少整個(gè)問題解決的復(fù)雜度,從而讓自己的工作更加順手蒸绩,更加有保障衙四。
上面這個(gè)設(shè)計(jì)是不是聽起來很熟悉,對(duì)了患亿, 它跟微服務(wù)架構(gòu)是一個(gè)理念传蹈。
通過這個(gè)分解,每一個(gè)小部分作為一個(gè)單獨(dú)的repo。每個(gè)repo,可以分給不同的小組來開發(fā)和管理卡睦。每個(gè)小組只需要關(guān)心這一小部分工作就可以了宴胧。每一個(gè)小的部分都可以單獨(dú)的進(jìn)行測(cè)試和開發(fā)。這個(gè)是好的一個(gè)方面表锻。
下面來說一個(gè)壞的方面恕齐。因?yàn)槊總€(gè)小組可以各自為戰(zhàn)。這樣就給協(xié)同工作帶來很大的問題瞬逊。比如說一個(gè)小組的模塊進(jìn)行了升級(jí)显歧,導(dǎo)致現(xiàn)有的大系統(tǒng)其他模塊兒無法正常工作。這種現(xiàn)象在微服務(wù)架構(gòu)系統(tǒng)的開發(fā)中非常常見确镊。
如果把這個(gè)壞的方面再發(fā)揮到極致士骤,就是每個(gè)組件之間互相依賴互相破壞,這樣子你整體系統(tǒng)可能就陷入萬劫不復(fù)的深淵蕾域。也就是說拷肌,隨著微服務(wù)架構(gòu),繼續(xù)把模塊兒進(jìn)細(xì)化旨巷,每個(gè)模塊失去了緊密的聯(lián)系巨缘,與此同時(shí)又沒有很好的管理機(jī)制把握全局, 導(dǎo)致整個(gè)項(xiàng)目開發(fā)失去了控制采呐,這也是很多微服務(wù)架構(gòu)系統(tǒng)失敗的原因若锁。
所以在multirepo的開發(fā)過程中,非常重要的一點(diǎn)就是避免過度的細(xì)分斧吐。一定要有一個(gè)機(jī)制來把握全局又固,時(shí)刻監(jiān)控整個(gè)開發(fā)環(huán)境是否正常。
制定標(biāo)準(zhǔn)是一個(gè)很有意思的話題煤率, 雖然說技術(shù)上很難爭(zhēng)高下, 但是總會(huì)辯論出一個(gè)最好的方案來仰冠,但是最嚴(yán)重的有時(shí)候根本不是技術(shù)上的問題。這個(gè)里面就會(huì)有很多說不清道不明的問題了蝶糯。
就因?yàn)槿绱嘶ν#谝恍┐蠊井?dāng)中,因?yàn)槿藛T的素質(zhì)都比較高裳涛,都是高手木张,常言說一山不容二虎,這里山中有好幾只端三,幾十只老虎舷礼。在這種情況下,用一只老虎的標(biāo)準(zhǔn)來把握全局是很難的郊闯。
所以寧愿犧牲一些下載時(shí)間妻献,編譯時(shí)間上的代價(jià)蛛株,最終他們還是繼續(xù)使用monorepo的模式。
還有一個(gè)在multirepo中不可忽視的一個(gè)問題就是為了保證一個(gè)功能的完整運(yùn)行, 即使再小的改動(dòng)育拨,也有可能對(duì)所有的repo進(jìn)行更新谨履。這是一個(gè)非常煩人的過程。
我工作過的一個(gè)multirepo項(xiàng)目熬丧,它里面有20多個(gè)模塊笋粟。要想使整個(gè)系統(tǒng)工作完整,你需要把這20多個(gè)模塊都下載到本地來析蝴,當(dāng)然害捕,你可以采用一些比較簡(jiǎn)潔的方式,比如說docker container的image, 盡可能的減少與過多的模塊兒直接的接觸闷畸。在這種模式模式下我相信你是非常喜歡黑盒模式的尝盼。因?yàn)槟K太多,你根本不想搞清楚它里面到底在干什么佑菩。只要能給你工作就行了盾沫。一個(gè)是太煩人,另外一個(gè)是時(shí)間太緊張了殿漠。
那么現(xiàn)在的問題就是赴精,上面兩種模式哪種更好呢?我的觀點(diǎn)是凸舵,不管你喜歡哪種模式祖娘,選擇哪種模式失尖,他們都是你的工具啊奄,你要控制他們,而不是他們控制你掀潮。
這種模式的本意都是想讓你的工作做得更好菇夸。
Monorepo你需要做的是盡可能的把你的測(cè)試案例細(xì)分開。這樣你在提交一個(gè)修改的時(shí)候仪吧,就不需要把所有的測(cè)試都過一遍庄新,那樣太費(fèi)時(shí)間了。
Multirepo對(duì)于你自身模塊的測(cè)試案例薯鼠,你需要做的是把與你的模塊相關(guān)的測(cè)試案例都放進(jìn)來择诈。在你提交一個(gè)修改的時(shí)候,要保證所有的這些案特殊案例都通過出皇。如果需要下載相關(guān)模塊的修改更新羞芍,要盡快通知大家去下載。
一個(gè)很常用的模式是這兩種模式的結(jié)合郊艘。你比如說一個(gè)修改荷科,你可能需要修改很多個(gè)repo唯咬, 那你可以考慮把這多個(gè)repo合成一個(gè)。
關(guān)于這個(gè)話題還有很多要可以談的畏浆,我們這一期就先談這些吧胆胰。
這里是丁哥開講,歡迎關(guān)注防止失聯(lián)刻获。