一種輕量級的代碼資產管理思路
「代碼管理還分輕量和重量?」,想必不少被標題吸引進來的朋友會有此疑問。在此,請容我解釋一二:
1、注意,這裡提到的是「代碼資產」,而不是「代碼」。
2、為了給後續的討論設定一個基準,本文所指的「代碼資產」主要是指企業自己生產的源代碼、相關文檔,以及由此產生的二進位製品。至於企業外購的各類軟體包,不在本文討論之列。
3、所謂輕量級,自然是指務實且容易上手。
既然設定好了討論的範圍,接下來就讓我們進入正題。
為什麼要對代碼資產進行管理?
按照套路,在推銷一種管理方法和手段之前,當然要先談談它的必要性。就本文涉及到問題域來說,主要是:
1、保障日常開發的順利進行,避免出現各種不一致和潛在的錯誤。典型的:內部代碼不一致、代碼變更缺乏管理……
2、保護企業自身的知識產權,為組織代碼設定各級保護機制,避免不必要的開發人員拿到不必要的代碼。比如:對於每一個項目成員,都不得不check out所有代碼才能進行開發。
對於第一點,大家應該並不陌生,因為到現在為止已經有各類書籍都從不同角度對它進行了闡述。不要以為它僅僅就是版本管理而已,其實它是:問題跟蹤、版本控制和持續集成的一個綜合體。要想保障開發的順利進行,這三個方面必不可少。
對於第二點,我猜考慮的人可能並不多。一來是因為這個問題本來就不是大多數開發者關心的領域;二來不少公司才剛剛把第一個問題解決,至於這一個問題,那就先往後放一放吧。當然啦,還有一個更重要的原因是:專門從代碼資產角度去討論解決這個問題的文章並不多,導致看上去對於這個問題缺少行之有效的手段和方法。
其實呢,問題的解法已經散落於各類文章和書籍之中,只是由於作者沒有突出強調它們針對知識產權保護方面的作用,導致不引人注目。而本文的目的就是將這些遺珠聚攏在一起,然後打包作為一個整體呈現於各位看官面前。這種做法姑且算作「知識集成」吧,:)。
代碼資產管理的3個層次
回答完了「WHY」,那就讓我們看看「HOW」。在這裡,我仿造CMM的做法來對代碼資產管理定義幾個級別。因為在我看來,這幾種做法屬於層層遞進,代表了管理方式的不斷提高。
當然,為了呼應標題中的「輕量級」,以及前文所倡導的務實易上手,我會推薦相應的配套工具。由於我本人的Java相關背景,所推薦工具主要以Java係為主。但相信我,下文所列的各種方法並非語言特有的,其他成熟的語言和技術體系肯定有其對應物,讀者可按圖索驥自行探索。
Level 1:源代碼
大多數像樣的公司基本都做到了這一層次,正如我前文所言,連這都沒有達到的公司只能算是「烏合之眾」。
鑒於有很多開發書籍已經對此都有比較詳細的闡述,本文也不打算對此說得太多。它基本上是這樣一個循環:Ticket — 開發 — 集成。每個階段都有值得注意的實踐:
Ticket
凡Commit必有Ticket,包括:「新特性」和「Bug」。
將每個Ticket作為一個「微文檔」,應用相應的Ticket模板。
開發
應用分支,可參考這份廣為流傳的分支模型,雖然我個人認為有點太複雜。我個人主要推薦:特性分支和發布分支。
主控庫 + MR,參考開源社區的開發模式。
重視Commit Message,這裡有一篇不錯的文章可以參考。
集成
MR自動觸發測試
集成流水線
相應的工具列表:
Gradle完成構建
GitLab和Git負責Ticket、日常開發和提交流程管理
Jenkins負責持續集成
自動化測試:
單元測試和集成測試:Spock + Jasmine
壓力測試:Gatling
功能測試:Geb + Phantomjs(現在可以考慮Headless Chrome了。)
還有一點容易忽視:代碼質量。如果將代碼視為資產,垃圾代碼無異於不良資產,最好在Commit前就能剔除。像類似CheckStyle、Findbug和Codenarc這類工具可以提供一定幫助,如果使用Gradle,可以考慮這個插件。當然啦,你也可以選用Snoar。不過請注意:在切實提高團隊的代碼能力之前,不要對這裡的工具抱有不切實際的幻想和要求。
最後,對於代碼許可權的管控,這裡就不再贅述,這完全取決於你的開發組織和工程要求。基本上跟系統的訪問控制如出一轍,沒什麼特別的。
Level 2:二進位製品
源代碼級別的管控很好的解決了開發團隊內部的代碼資產管理,但開發團隊之間的呢?比如:A團隊依賴於B團隊的組件。最簡單的辦法當然是兩個團隊共用一個版本庫或者依賴於類似Git中的Submodule這樣的機制。但是,你有沒有想過假如B團隊的組件是一個基礎組件,同時服務於3+個團隊,這種情況下該如何處理?
同時,我反對在這樣的情況下繼續以源代碼形式來操作的原因除了顯而易見的煩人之外,還有:
1、不同團隊依賴B團隊組件的不同版本,這種情況下,採用源代碼來管理幾乎無解。
2、不同團隊使用的語言不同,並非所有團隊對於B團隊組件的依賴是以類庫或SDK的形式體現。對於以Restful API形式依賴該組件的團隊來講,直接依賴源代碼是不現實的。
3、不同團隊涉密級別不同,可能B團隊的組件屬於組織的核心競爭力,即使在組織內部也不是所有人有資格和有必要接觸到它的源代碼。
很明顯,以上的考慮已經將「源代碼共享」這種方式排除出局了。此時,解決問題的辦法只能是從二進位製品的管理上著手。
這裡,分兩種情況考慮。
Jar包或SDK
對於依賴管理,Java開發領域已經有很成熟的解決方案:Maven倉庫。這比起自己編譯加到處拷貝的方式不僅成熟而且要簡單很多,想想你怎麼解決不同項目對於組件不同版本的依賴問題吧!
看到這裡,有經驗的朋友應該已經明白我的意思:搭建一個私有的Maven倉庫,然後將B團隊組件發布到這個自有倉庫中。其他依賴者只需像平常一樣將相應的依賴添加到build文件中就ok了,這樣一來,以上3個問題迎刃而解。
對於B團隊,只需做好自己發布流程的管理;對於其他依賴團隊,只需明確自己需要使用的版本就好。哇,整個世界一片祥和,皆大歡喜。
在這裡,值得注重的實踐:
借鑒開源社區的版本策略和發布流程,典型的如語義版本。
建立相關的Wiki和項目反饋機制,GitLab對此已經有很好的支持。
如果符合組織內部開源政策的要求,直接發布到公用倉庫,建立相應的開源項目主頁,接收社區貢獻,省事!
還有,就是別忘了對私有庫進行備份!這一節對應的工具有:
私有庫:Nexus
Gradle的Maven插件
遠程API
隨著組織的發展,團隊的多樣性也會增加,不見得所有的團隊都採用相同的開發語言和技術體系。而且,隨著類似「前後台分離」這樣的開發實踐的普及,即使同一項目組內部也會有不同的技術體系。這種情況下,Jar包或SDK策略就難以實施。尤其是後者,總不能針對每一種開發語言都維護一套SDK吧。
此時,最好的解決辦法就是求助於一種通用的調用機制,滿足不同語言的調用需求。當前,這一機制就是Restful API。明確了技術路線,接下來就簡單了。因為時下流行的微服務架構對此早有解決方案:
按名字引用遠程API,避免直接將服務的地址寫死。
參考現有的Restful API版本方案,最好開發框架本身對此也有很好的支持。
針對API發布、調用和管控的一攬子解決方案。
引入UAA和API Gateway。
說得直白一點,面對多語言開發團隊之間的開發協作和管理,微服務是目前的最佳方案。在Java生態中,目前最全面的當屬Spring Cloud。在API領域,其他值得關注的技術和工具還有:
GraphQL
OpenAPI
gRPC
HashCorp系
當然還有我比較喜歡的Vert.x
最後,自賣自誇一下,對於API的Mock工具,可以瞧瞧我開發的dgate,簡單且方便,;)。
Level 3:插件架構
解決完團隊間的依賴,讓我們再看一看這樣的場景:項目組內部不同涉密部分的管控。這種情況介乎於「源代碼依賴」和「二進位依賴」這兩個管控層級之間:
1、從邏輯上來講,他們是一個項目。只不過經過組織考驗的同學可以接觸到核心層的代碼,而另一撥同學只能接觸該他們接觸的部分。
2、從物理上來講,這又確實是不同的項目組。但這些項目組間的依賴關係比前面的依賴關係更緊密:後者的價值附著於前者之上才得以體現,單獨存在則沒有任何價值。
或許有同學會說,這本質上還是二進位製品的依賴問題,照搬前面的做法就夠了。理論上是這個道理,但在集成方面,這種方式則顯得過重,並且不利於項目組間的緊密協作。畢竟,如前所言,這在邏輯上來講其實是一個項目組!
此時,我們可以求助於插件架構,將整個項目插件化,實現核心層和外圍層的分離,進而實現相關負責人的分離。核心層負責集成和調度,外圍層負責具體功能實現。但是離開了核心層,外圍層幾乎無法獨立生存,自然也就沒有價值。這種思路其實跟硬體的生產管控方式如出一轍:外圍工廠負責單個組件或模塊的生產,所有的裝配在內部完成。
插件化很好的完成這樣兩個目標:
1、團隊成員的分工協作。
2、保護好了核心知識產權的可控。
尤其是後者,它避免所有成員為了項目開發不得不接觸所有源代碼。即便是負責插件的同學,如果為了調試,他完全可以直接使用預編譯好的項目工程,通過將插件放入相關的插件目錄,讓整個工程載入插件,進而完成調試。
如果為了更進一步控制,可以引入證書機制,發行開發用的臨時證書,避免這類預編譯的內部項目外流。當然,這一手段不是本文關心的重點。
並且,這裡提醒一下:此處講的插件是「真·插件」,即非開發用的插件,如Grails Plugin或JQuery Plugin。後者本質上其實跟類庫是一回事。這裡的插件更像是一個設備的零部件,一個實實在在的功能實體。
在Java生態中,如果要實現插件架構,PF4J是一個不錯的選擇,值得你擁有。我曾經用它實現了一個簡單的小工具,很方便。
當然,你也可以說,如今是微服務的時代,用微服務也可以達到類似的效果。對此,我不能說錯。但,多一個選擇總是不錯的。
總結
本文主要從技術和架構設計的角度闡述了代碼資產管理的若干方法,並針對不同級別給出了相應的技術方案和支撐工具,以貫徹我一直倡導的「可落地」方案。
至於其他,如某些大公司那般「不允許帶U盤」等這樣的管理制度,不在本文的討論之列。這類機制雖有參考價值,但不具備通用性,一般需要根據實際情況量體裁衣。最關鍵的是,我認為「好的技術支撐會大大降低管理成本和制度要求」。這也是我將之稱為輕量級的原因。
希望本文能給大家帶來幫助,也歡迎各位指正!
作者:胡鍵


TAG:DevOps時代 |