關於代碼的管理問題已經討論多年,隨着企業業務的複雜度提升、軟件行業技術棧的選擇度變寬泛,現代軟件的代碼倉庫也變得愈來愈龐大和複雜。一箇中型項目,將測試代碼、核心業務代碼、編譯構建、部署打包等基礎設施的代碼所有加起來,幾十萬行都是屢見不鮮。而且一個項目每每由多個團隊進行協做,如何讓多團隊在對同一個項目的代碼進行協做時不會相互干擾、相互制約,也是每一個企業研發團隊在實踐中不斷摸索的難題。前端
對於上文所說的一些問題,業界已經概括了常見的代碼倉庫存放方式,常見的如單倉庫和多倉庫。大部分企業會針對不一樣的項目採用不一樣的倉庫管理機制,因此對於企業來講,常常會兩種方式並存:git
將全部項目代碼存放在一個代碼倉庫當中,這個好處在於項目的全部開發者能夠共享看到項目中的全部代碼;在項目規模較小的時候,一個庫能夠更好地管理和維護,發版本只要統一發布便可;對於持續集成,也只須要針對一個庫維護若干條流水線。但再好的實踐以及工具都有它適用的範圍。Git 已是很是流行的代碼託管工具,但 Git 會把全部歷史記錄以及代碼同步到各個用戶的本地機器,因此對於大型項目而言,若是使用單倉庫,就意味着某個模塊開發者的本地可能有大量冗餘代碼和提交記錄的信息,這個時候拆分紅更小的庫顯得更加合適。編程
谷歌與 Facebook 就是業界典型的單倉庫派表明。做爲代碼行數已經超過數十億行、commit 數量累計達到千萬次的團隊(2015 年的統計數據),若是沒有強悍的基礎設施,也很難運轉順利。Google 曾發表論文介紹其強大的代碼管理系統 Piper 以及客戶端工具 CitC,但對於大部分企業來講是否有必要投入如此之大的研發成本去自研一個代碼管理系統值得商榷,因此谷歌的實踐對於大部分企業來講不必定具有參考性。後端
*谷歌代碼倉庫每週的提交數量架構
將項目代碼進行必定的拆分放在多個庫當中,好處就是將代碼進行必定的解耦,對於體型較爲龐大的項目來講管理上會更加清晰和富有彈性。將代碼按照必定邏輯分庫以後,倉庫與模塊有了自描述的特徵,讓一塊兒協做的開發者能夠一目瞭然。發佈源碼版本、持續集成構建時,負責各倉庫的研發組織能夠按照本身的節奏來發布,同時將一些「壞代碼」的影響控制在某個倉庫中,而不會影響項目所有代碼。分庫也有要注意的地方,在同一個項目裏的代碼多多少少都有業務上或者是技術上的聯繫,好比編譯依賴:以一個Java 項目爲例,客戶端接口的調用代碼到底是直接依賴服務端接口代碼的定義,仍是間接依賴?若是是間接依賴,那麼分庫管理是很是方便的,但同時客戶端就沒法快速感知到服務端接口定義的變化。因此在進行多倉庫劃分時,要注意劃分的一些經常使用原則。框架
多倉庫在業界使用的很是普遍,在騰訊、華爲、阿里的開源項目中咱們都能看到,好比騰訊的 Tars 開源項目(RPC 開發框架)就按照不一樣編程語言以及技術棧進行了分庫:包括 Java、Go、PHP 等子項目。做爲開源項目,一個清晰的分庫可讓開發者更好地協做,避免沒必要要的溝通成本。編程語言
*Tars 的開源項目子倉庫分佈式
CODING 在多倉庫實踐上也遇到過問題。因爲前端、後端、git-server 三個模塊的代碼放置在同一倉庫中,以致於代碼版本的 tag 須要保持同步,制約了各個團隊的開發節奏。每一個模塊的進度都得齊頭並進,才能保證最終版本是一致的。儘管它們在業務上緊密相連,但實際上這幾個模塊自己沒有編譯依賴,因此在沒有多倉庫功能時,咱們只能創建了三個項目,使用三個項目的代碼倉庫能力,只集中在一個項目當中進行項目管理工做。微服務
在千呼萬喚中,CODING 近期終於正式上線了多倉庫功能,咱們的開發人員也終於能夠告別傻乎乎地使用一個項目進行管理,又用多個項目進行代碼倉庫管理的尷尬問題,咱們將那些沒有編譯依賴的項目,但在業務上又有聯繫的代碼倉庫,放置在同一項目的多倉庫下,開發人員無需在多個項目中切換。工具
多倉庫功能一直是 CODING 想要投入作的一個特性。隨着近幾年 CODING 企業用戶的快速增加,CODING 的架構也面臨着持續的挑戰。如何讓交付更加順滑,讓特性更快、更好地服務開發者,是咱們進行架構演進的初衷。因此咱們在很早以前就開始了容器化、微服務化的規劃與實施,而在微服務化的過程中,包括代碼倉庫管理在內的研發流程與組織方式也在配套前進着。多倉庫這項基本能力就可讓多個微服務獨立存放在獨立的代碼倉庫當中,配套獨立的持續集成流水線,讓架構演進變得水道渠成。咱們知道不少企業用戶對多倉庫有很大訴求,CODING 的多倉庫已正式上線,歡迎你們前去體驗。
綜上咱們能夠看到,代碼倉庫的組織方式每每和人員組織架構息息相關,並且代碼庫的拆分也每每和軟件架構的演進息息相關。在現代軟件架構逐漸由單體朝着分佈式、微服務演化時,代碼倉庫和研發團隊的粒度也在逐漸變小,從之前的集中式慢慢變爲網狀。但不管是單倉庫仍是多倉庫,最終目的都是爲了讓開發者更加高效地進行研發。那究竟該如何選擇?筆者總結了幾條業界的通用實踐來供你們思考:
不一樣技術棧的編譯環境、構建環境、發佈環境每每不一樣,代碼之間的硬性依賴也不大,能夠考慮分庫存放。大部分的開發者仍是傾向於在工做中持續使用某一種熟悉的編程語言,因此按照技術棧劃分是一個經常使用的實踐。
拆庫要拆到什麼粒度呢?有些研發組織微服務化後,給每一個微服務都分配了一個代碼庫,隨着拆分深刻,一個項目積攢了幾百個代碼庫。但一個 two-pizza 團隊每每會負責多個微服務,不只僅是一個。因此建議不要盲目使用大量代碼庫,避免到後期難以管理,能夠考慮按照團隊組織來劃分代碼倉庫。
很多企業代碼拆分以後可能順便就把團隊之間的代碼權限也作了劃分,建議研發團隊慎重考慮。關閉了代碼權限就意味着,團隊與團隊之間再也不互相 review 代碼,相應的工做上的交流也會逐漸減小。若是讀者的企業屬於內部開放型氛圍的公司,或者想要成爲開放型的公司,那麼關於此點請三思。