10分鐘將你的Go工程轉換爲Go Module模式

引言
自從在Go 1.11和更高版本中引入了Go的新的依賴管理系統以來,GoLang開發人員已經接受了包版本控制解決方案。這樣作的用戶可使用GoCenter存儲庫中的不可變公共Go 模塊,並經過更健壯、更可靠的Go Pipeline得到更快的構建速度。git

可是,將現有的項目轉換爲使用Go Module並不老是很容易,尤爲是若是該項目已經嘗試過GoLang的其餘包管理解決方案時。緩存

爲了幫助GoLang社區正確地使用Go Module,咱們將使用開源的etcd項目(Kubernetes使用的鍵值數據存儲)做爲示例。這是一個最佳實踐的實際示例,由於它足夠複雜,能夠展現一些常見的實踐網絡

PS:
在上一篇關於Go語言開發的的文章中(傳送門:Go 語言依賴管理的優點),咱們介紹了Go 依賴管理的發展歷史以及Go Module如何更有效的幫助咱們管理Go語言項目的依賴。今天咱們重點分享如何將你的Go 項目轉換爲Go Module 項目。ide

Go 項目依賴管理痛點分析
傳統GO項目進行第三方模塊依賴時,每每是去下載第三方源碼,這種方式將存在如下常見問題:
1.性能及穩定性:每次下載從各大VCS系統下載源碼性能低,依賴網絡環境,穩定性差
2.一致性&可重複性:容易收到依賴源的影響,咱們每每在感知不到模塊提供方的改動時,就下載了新版的代碼,兩次依賴某模塊獲得的依賴不一致,每每形成前一秒還行,下一秒構建失敗的情形,尤爲在持續集成系統中
3.協做:源碼方式模塊基本無版本概念,或不是語義類型,多團隊協做困難工具

基於以上問題及痛點,建議轉換爲Go Module 模式管理Go 項目依賴。附Go Module 基於Go Proxy進行依賴下載的原理圖:
10分鐘將你的Go工程轉換爲Go Module模式性能

應用Go Module方式後能夠得到如下收益:
1.可用性(標籤tag能夠從VCS中刪除)
2.不變性(能夠在VCS中進行更改)
3.快速:(沒有git克隆,沒有計算元數據,調用更少,性能好)
4.本地統一存儲緩存($GOPATH/pkg /mod/cache)測試

Go模塊轉換最佳實踐
咱們以ETCD項目爲例進行轉換,這個轉換過程已經過測試用例的驗證,能夠到該項目中的Pull Request中查看ui

步驟一:準備go.mod文件
對於之前從未使用過模塊的項目(沒有go.mod 文件),或者任何如今不推薦的依賴項管理解決方案,這個過程都很是簡單。您只須要在項目的根目錄中運行go mod tidy。這將生成一個新的、已填充好該項目依賴描述的go.mod文件。版本控制

可是,若是項目使用了那些較老的解決方案之一,好比dep、glide、govendor或godep,那麼您將須要運行go mod init來生成填充的go.mod文件。該命令支持舊格式中依賴項描述。blog

etcd項目確實有一個go.mod文件,儘管它從未在項目的構建系統中啓用。問題是模塊名稱沒有正確的版本標識符,由於當前版本標記是v2+。因爲語義化導入版本控制的影響,須要更改成v3。

其包括執行如下過程:
1.更新etcd的go.mod文件以修正模塊名稱,使其包含v3後綴。
10分鐘將你的Go工程轉換爲Go Module模式
2.更新全部代碼中的Import以包含版本號。咱們編寫了一個腳本,以便更容易地修改全部引用。完成後,此更改以下:
10分鐘將你的Go工程轉換爲Go Module模式

步驟二 : 啓用Go模塊
要使go客戶端可以使用go module,須要設置GO111MODULE=on

正如咱們所指出的,etcd項目已經設置了go.mod文件,有人可能認爲這已經完成了。但它沒有,而該環境變量這種缺失證明了該項目尚未使用go module。

注意:從Go 1.13開始,這一步將再也不須要,由於Go Module將在默認狀況下啓用

步驟三 : 更新測試中的導入

在上面的過程當中,咱們對組成etcd主模塊的go.mod文件進行了更新,以使用v3版本標記。如今主模塊被標記爲v3,咱們還須要更新etcd項目的測試用例中的Import引用v3,以確保它們導入了主模塊的正確版本。

步驟四 : 其餘更新

在這些更改以後,您可能但願保持良好的狀態—畢竟,應用程序模塊如今已經所有轉換爲使用go module,並使用正確的版本標記。

不過沒那麼快。一旦你開始運行測試,你會發現兩個額外的場景須要處理:

1.etcd使用了諸如golint、gosimple、staticcheck、ineffassign等靜態分析工具,但其中一些工具沒有模塊意識,沒法識別模塊路徑,而沒法經過必要的檢查。在etcd的這種場景下,etcd-io/etcd下並無v3文件夾,可是Import導入(或模塊路徑)包含v3,如etcd-io/etcd/v3。其餘工具是模塊感知的,但必須在新版本的Go 1.12中可用。若是構建系統在1.11之上,那麼它們也須要遷移到1.12。

2.若是使用了protobuf之類的代碼生成器。更新.proto文件,以便使用正確版本的導入生成代碼。

步驟五 : 加入GoCenter

在構建過程當中,您可能會注意到許多go get命令在etcd的不一樣階段執行。

爲了加快GoLang應用程序的構建時間,並確保etcd ppipeline中使用的Go Module版本的不可變性和可用性,使用GoCenter來構建etcd
只需設置GOPROXY=https://gocenter.io。(詳細原理可看上文的Go Proxy 原理圖)
總結

正如您所看到的,將Go項目轉換爲使用Go Module方式很是簡單,可是有一些細節可能會減慢您的速度。經過選擇這個具備豐富場景的項目來演示這個過程,咱們相信咱們達到了大多數須要處理的場景,爲您提供了一個很好的示例,覆蓋了您可能面臨的狀況。

最後你們感興趣能夠測試一下舊的依賴管理方式和Go Module方式的性能對比,請參考:
https://jfrog.com/blog/build-times-matter-speed-is-everything/

相關文章
相關標籤/搜索