GoCenter助力Golang全速前進

一、背景

Go語言是Google開發的一種靜態強類型、編譯型、併發型,並具有垃圾回收功能的編程語言。爲了方便搜索和識別,有時會將其稱爲Golang。自2009年11月Google正式宣佈推出,成爲開放源代碼項目以來,Go語言已成爲當今開發人員和DevOps領域最流行的語言之一, 它被用於設計和編寫Kubernetes和Helm。但是,相比語言本身已經得到了廣泛的普及和使用,Go語言的包管理方案卻大大滯後了。

Go語言生態系統中缺少的是標準化——沒有用於依賴關係管理的標準工具, 也沒有標準的包格式或兼容的包倉庫規範。這意味着開發人員無法使用Go語言創建可重現的構建, 這是一個相當大的問題。這些年來, 社區推出了諸如dep、godep、glide和govender等工具,試圖用來處理Go語言的依賴管理, 但並未成功。2018年Google在Go1.11官方推出了Go modules,爲Go語言提供了支持版本化的依賴管理方案。

Go modules現在已成爲Go語言標準的依賴管理工具和包倉庫規範。而GoCenter爲Go modules的實現和推廣提供了依賴包的公共倉庫,使得Go語言的開發人員能夠更爲穩定和方便地開發可重複構建的Go應用程序。

 

二、Go語言的依賴管理

在介紹GoCenter之前,我們先簡要地回顧一下Go語言依賴管理的發展歷程。

Go語言在推出之初,並沒有明確的依賴管理方案。只是在構建過程中通過go get命令,將用import聲明的依賴從對應的源,通常是git上的項目,下載到$GOPATH/src目錄下,和Go應用自身的代碼放在一起。這種依靠GOPATH來管理依賴的機制帶來的問題 是顯而易見的,比如:

  • 因源依賴包自身的變化,導致不同時間構建Go應用時go get得到的依賴實質上是不同的,即不能實現可重複的構建;
  • 或者因源依賴包自身的變化,重新構建Go應用時會引入不兼容的新實現,導致Go應用無法通過編譯。

因此在1.5版本以前,爲了規避這個問題,通常需要將使用的依賴包手工拷貝出來。

爲了實現Go應用的可重複構建,Go1.5引入了Vendor機制。Vendor機制的核心就是在GOPATH下面增加了vendor文件夾。Go應用所需的依賴都可以從依賴源fork出所需的分支,存放到vendor文件夾。當構建Go應用時,Go編譯器會優先在vendor文件夾下搜索依賴的第三方包,vendor文件夾下沒有才會再到$GOPATH/src下去找。這樣只要開發者預先將特定版本的依賴包存放在vendor文件夾,並提交到Go 項目的code repo,那麼所有人理論上都會得到同樣的編譯結果,從而實現可重複構建。 在Go1.5發佈後的若干年,Go社區把注意力都集中在如何利用Vendor機制解決Go應用的依賴管理問題,並誕生了衆多的依賴管理工具,如dep、golide、govendor等。然而,和Java的Maven、Python的Pypi、C/C++的Conan等業界成熟的依賴管理方案相比,Vender機制仍然存在許多問題,比如:

  • Vendor文件夾中的依賴包沒有版本信息。這樣依賴包脫離了版本管理,對於一致性管理、升級,以及問題追溯等場景,都會難以處理;
  • Vendor機制沒有給出如何能夠方便地得到Go項目依賴了哪些包,並將其拷貝到vendor文件夾下的方案,多數情況下還需要到不同的Git源項目裏手工拷貝;
  • 當依賴的包比較多的時候,vendor文件夾也會變得非常龐大。

2018年年初,Go核心Team的技術leader,也是Go Team最早期成員之一的Russ Cox個人博客上連續發表了七篇文章,系統闡述了Go team解決“包依賴管理”的技術方案:vgo。vgo的主要思路包括:語義導入版本控制(Semantic Import Versioning)、最小版本選擇(Minimal Version Selection)、以及引入Go module等。同年5月份,Russ Cox的提案“cmd/go: add package version support to Go toolchain”被社區接受,vgo的代碼合併到Go主幹,並將這套機制正式命名爲“go modules”。由於vgo項目本身就是一個實驗原型,merge到主幹後,vgo這個術語以及vgo項目的使命也就此結束了。後續Go modules機制將直接在Go主幹上繼續演化。

Go modules機制的主要變化包括:

  • 去除了飽受詬病的GOPATH的限制。Go編譯器將不再到GOPATH下面的vendor或src文件夾下搜索Go應用構建依賴的第三方包;
  • Go modules機制爲在同一應用repo下面的包賦予了一個新的抽象概念: 模塊(module),即可重用的Go代碼包,並啓用一個新的文件go.mod記錄模塊的元信息和依賴關係。而在go.mod裏明確描述了依賴包的版本信息,同一個依賴包也可以記錄多個不同的版本。除了精確版本外,go.mod還支持用表達式模糊地定義依賴版本;
  • 在Go modules機制下,還支持創建Go依賴包的公共倉庫。這是因爲應用程序包含的Go模塊,必須從數千個獨立的源代碼存儲庫中解析,而每個存儲庫的維護紀律可能各不相同。因此,需要存在一個可公開訪問的存儲庫,通過Go modules提供的依賴描述、解析機制,爲Go的開發者提供一致的、可分享的、支持重複構建的、穩定的Go依賴包源。GoCenter就是這種Go依賴包公共倉庫的重要實現。

 

三、GoCenter簡介

GoCenter通過創建Go模塊的公共中央倉庫,提供可重複和快速依賴解析的依賴包管理方案,解決了Go開發人員查找和獲取Go依賴包的困難。GoCenter將直接從源代碼存儲庫獲取Go項目,轉變爲處理和驗證不可變的、具備版本控制的Go模塊, 並將其免費提供給Go應用的開發人員。

GoCenter(https://gocenter.io)提供了通過公共Go代理解析模塊, 包括通過託管免費服務搜索模塊的能力。從創建開始, GoCenter已經包括了數千個廣受歡迎的 Go項目的模塊, Go開發者可以立即使用這些項目進行自己的構建。

 

開發人員也可以提交自己的Go項目加入GoCenter,以便將其提供給Go社區開發者,從而得到更爲廣泛地應用。

 

GoCenter這個中央倉庫,提供了預先打包,以及版本化的Go模塊,使得Go開發人員或團隊不再需要爲使用公共模塊而構建自己的模塊庫, 從而消減了使用 Go 語言的巨大成本。

此外,如果Go開發者或團隊已經有了自己的JFrog Artifactory倉庫,就可以通過配置指向GoCenter的遠程倉庫,爲重複構建提供完全的本地化控制,並可以預防訪問GoCenter的網絡連接問題。

 

四、基於GoCenter構建Go應用

要構建Go應用項目,首先需要安裝Go客戶端(版本1.11.0 或更新的版本) 。而安裝Go之後,有三種方法可以從GoCenter解析Go模塊:使用goc、使用 go 客戶端,或部署本地倉庫(如Artifactory),以代理GoCenter。

 

1、使用goc

推薦在構建中使用GoCenter的方式是通過goc工具。goc工具包裝了Go的客戶端,器, 能夠使用GoCenter中的包正確構建Go應用,而無需手動設置。

要安裝goc,需要使用以下的curl命令,或按照gocgithub主頁(https://github.com/jfrog/goc)的說明:

$ curl -fL https://getgoc.gocenter.io | sh

然後, 就可以Go項目的根目錄中運行任何命令, 就像運行Go命令一樣。例如:

$ goc build

goc工具自動分配GOPROXY連接GoCenter,所以能夠優先從該倉庫解析Go的依賴包。對於在GoCenter找不到的包,goc將會試圖通過源代碼控制系統來解析它們,以更好地保證成功構建Go項目。

Go客戶端自身不能執行這種輔助操作(請參閱下文), 因此至少在 GoCenter能夠爲大多數Go開發人員提供可能需要的所有依賴之前,仍然建議使用goc。

 

2、使用Go客戶端

推薦在構建中使用GoCenter的方式是通過goc工具。goc工具包裝了Go的客戶端,器, 能夠使用GoCenter中的包正確構建Go應用,而無需手動設置。

如上所述,使用GoCenter時並不建議直接利用Go客戶端進行構建,因爲當在GoCenter找不到相關依賴包時構建會失敗。對於Go客戶端這種限制的詳細信息,可以參考相關的issue和修正信息(https://github.com/golang/go/issues/26334)。Go開發人員還是應該改用goc。

當然,如果在充分了解這個限制還希望使用的情況下,也是可以使用Go客戶端的。

如果希望構建Go項目時從GoCenter中獲取相關依賴包,需要設置GOPROXY指向GoCenter的URL,https://gocenter.io

$ export GOPROXY=https://gocenter.io

現在就可以使用Go客戶端構建Go應用了:

$ go build

 

3、部署代理GoCenter的私有倉庫

如果使用的是如Artifactory這樣的私有倉庫,則只需設置GOPROXY指向該私有倉庫,而把GoCenter創建爲該私有倉庫當中的遠程倉庫。

爲了要在Artifactory裏創建代理GoCenter的遠程倉庫,需要遵循以下步驟:

1. 創建新的遠程庫,並設置包類型爲Go;

2. 設置遠程倉庫的名字,並在URL字段輸https://gocenter.io/

3. 點擊“保存 & 完成”按鍵。

還可以創建虛擬倉庫,用以聚合同時從本地Go倉庫和遠程倉庫獲取的Go依賴包。

一旦在Artifactory裏配置好使用GoCenter,就可以使用標準的GOPROXY方式基於Artifactory進行構建。需要注意的是,根據Artifacotry的設置,需要適當地處理客戶端的認證信息應爲當前Go客戶端在獲取模塊時不會發送相關認證信息的,所以處理起來是有一定難度的。因此,當使用Artifactory代理GoCenter時,建議使用JFrog CLI來構建Go應用當配置好JFrog CLI和Artifactory的關聯之後,就可以使用類似於

“jfrog rt go build”的命令來從Artifactory獲取依賴,並構建Go應用。

使用JFrog CLI的好處是可以方便地向Artifactory上傳針對特定構建而創建的依賴包,也同時內置支持生成和發佈與構建過程相關的元數據。詳細信息,請參考JFrog CLI的相關文檔。

 

五、搜索Go模塊

GoCenter首頁中的搜索框可幫助按特定模塊名稱(例如, "虹膜")進行搜索。當執行搜索時,GoCenter將列出與搜索名稱匹配或部分匹配的模塊。

 

點擊列表中的某個模塊,將會列出GoCenter中該模塊的所有版本:

 

列出的版本都利用顏色編碼來指示其當前的可用狀態:

綠色,表示該模塊版本已在GoCenter之中且處於可用狀態;

紅色,表示該模塊版本不存在,而且不可用;

灰色,表示該模塊版本正在引入的過程中,尚未可用。

搜索結果還會顯示那些Go項目在相關Git代碼庫存在,而在GoCenter尚不存在的模塊版本列表。如果有這樣的缺失版本,可以通過單擊“Add missing version(s)”把它們 添加到GoCenter。

 

六、提交自己的Go模塊

如果希望將自己的Go項目添加到GoCenter,使其可被Go社區的開發人員使用,則需要提交相關的加入申請。

首先可以對希望加入的模塊名執行搜索。如果相關模塊並不存在,則可以單擊“Add”圖標來請求添加模塊。一旦點擊,將會看到加入申請表格。在表格中,可以輸入申請加入的Go模塊的URL。通過搜索該模塊的結果可以查看該模塊的加入進度。

GoCenter將依據以下最低標準來驗證加入請求:

  • Go模塊位於gihub.com或gopkg.in上的公共項目(repo);
  • 該項目沒有被設置爲存檔狀態(archived);
  • 該項目至少擁有3顆星

 

七、總結

自從2007年首次在谷歌構想,並於2009年正式推出,Go語言很快就成爲最流行的編程語言之一。事實上,Helm和Kubernetes都是用Go語言編寫的。在2017年的一項調查中,Go語言在開發者的偏好中排名最高,67%的開發者都在利用Go語言編程。

爲此, 我們期望GoCenter能夠爲不斷增長的Go社區和開發人員提供必要的服務,並幫助Go語言更加符合DevOps的需求。

通過訪問GoCenter,https://gocenter.io,可以發現經常使用的Go依賴包都已經包含在其中了。如果還沒有,請提交相關的加入申請。

GoCenter管理了版本化的Go模塊,可以和Go應用構建使用的任何CI服務器或私有倉庫進行對接。而使用JFrog CLI和Artifactory,可以使得這一過程更加便捷。

想要了解有關 GoCenter 更多深入的技術信息?查看GoCenter的Github項目,https://github.com/jfrog/gocenter

 

八、參考文獻

Golanghttps://golang.org

Go & Versioning: https://research.swtch.com/vgo

GoCenterhttps://gocenter.io/

          https://github.com/jfrog/gocenter

goc https://github.com/jfrog/goc

JFrog CLI:https://www.jfrog.com/confluence/display/CLI/CLI+for+JFrog+Artifactory

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章