為什么要使用 Go module proxy
本文是 Go語言中文網(wǎng)組織的 GCTT 翻譯,發(fā)布在 Go語言中文網(wǎng)公眾號,轉(zhuǎn)載請前往聯(lián)系授權(quán)。
在看過 Go module 的簡介之后,我以為我已經(jīng)知道了這個功能我需要知道的一切。但是很快,我意識到并不是這樣。最近,人們開始提倡使用 Go module proxy。在研究了利弊之后,我得出結(jié)論,這將是近年來 Go 語言 最重要 的變化之一。但為什么會這樣呢?是什么讓 Go module 代理如此特別?
使用 Go modules 時,如果向干凈的緩存的計算機上添加新依賴項或構(gòu)建 Go module,它將基于 go.mod 將下載(go get)所有依賴項,并將其緩存以供進(jìn)一步操作。你也可以使用 -mod=vendor 參數(shù)構(gòu)建 vendor 文件夾,來繞過緩存,以及后邊使用這些下載的依賴。
但以上兩種方法都不完美,我們應(yīng)該可以做得更好。
(不)使用 vendor 文件夾的問題
使用 vendor 文件夾的問題
在模塊感知模式[1]開啟時,使用
go命令,默認(rèn)不再使用vendor文件夾。如果你不附加-mod=vendor參數(shù),這個文件夾將不會被啟用。這通常引發(fā)問題,并導(dǎo)致必須使用其他陳舊的方案來支持老 Go 版本程序(請參考:在 Travis CI 上使用 Go Module 和 vendor[2])vendor文件夾,會占用大量磁盤空間,特別是在比較大的單體應(yīng)用中。這也將增加代碼倉庫的克隆時間。可能你認(rèn)為只用克隆一次,實際卻不是這樣。CI/CD 在每次事件(比如:pull request)都會觸發(fā)克隆代碼。因此,這將長期導(dǎo)致更長的編譯時間,并將影響團(tuán)隊中的每個人。使用新的依賴通常會導(dǎo)致難以審核代碼的變化。大多數(shù)情況下,你必須將依賴項與實際的業(yè)務(wù)邏輯捆綁在一起,這導(dǎo)致難以進(jìn)行更改。
不使用的 vendor 的問題
go程序?qū)⑷ピ创a倉庫下載這些依賴。總是存在任何依賴可能在將來消失的風(fēng)險(記住左邊的傳奇故事[3])。版本管理系統(tǒng)(例如
github.com)可能關(guān)閉。在這種情況下,你將無法再次構(gòu)建項目。有些公司不希望內(nèi)網(wǎng)接入外網(wǎng),此時,沒有
vendor文件夾,我們將無法使用。假設(shè)發(fā)布的依賴
tag是v1.3.0,并且已經(jīng)go get獲取它到本地緩存。此時,依賴的所有者可以通過推送具有相同tag的惡意內(nèi)容來破壞代碼庫。如果在具有干凈緩存的計算機上重建Go module,它現(xiàn)在將使用被破壞的包。為了防止這種情況,需要將go.sum和go.mod文件放在一起 。一些依賴使用不只使用
git作為版本管理系統(tǒng),還有可能使用hg(Mercurial),bzr(Bazaar) 或svn(Subversion)。而你的機器沒有安裝裝或者 Dockerfile 沒有配置這些工具,這都將引發(fā)問題。go get需要獲取go.mod列出的每個依賴項的源代碼來解決遞歸依賴(需相應(yīng)的go.mod文件)。因為它意味著必須下載(例如git clone)每個存儲庫以獲取單個文件[4],這顯然會使得整個構(gòu)建過程變慢。
那我們怎么解決這些問題呢?
使用 Go module proxy 的好處
默認(rèn)情況下, go 命令會直接從版本管理系統(tǒng)下載代碼。GOPROXY 環(huán)境變量允許在下載源的進(jìn)一步控制。配置該環(huán)境變量后,go 命令可以使用 Go module proxy。
設(shè)置環(huán)境變量 GOPROXY 開啟 Go module proxy 后,將解決上邊提到的所有問題。
Go module proxy默認(rèn)永久緩存所有依賴(不可變存儲)。這意味著,不必再使用 vendor 文件夾。拋棄
vendor文件夾,它將不會再消耗代碼庫的空間。因為依賴項存儲在
不可變存儲中,即使依賴項從網(wǎng)上消失,你的代碼也會受到保護(hù)。一旦
Go module(依賴) 存儲在Go proxy中,就無法覆蓋或刪除它。這可以保護(hù)你免受可能使用相同版本注入惡意代碼的攻擊。你不再需要任何 VSC 工具來下載依賴項,因為依賴項是通過 HTTP 獲取的(
Go proxy在后臺使用 HTTP)。下載和構(gòu)建
Go module的速度要快得多,因為Go proxy通過 HTTP 獨立提供源代碼(.zip存檔)go.mod。與從 VCS 獲取相比,由于更少的開銷,這使得下載花費更少的時間。相比之前它必須獲取整個存儲庫,解決依賴關(guān)系也更快,因為go.mod可以獨立獲取。Go 官方團(tuán)隊對它進(jìn)行了測試,他們看到快速網(wǎng)絡(luò)上的速度提高了 3 倍,而慢速網(wǎng)絡(luò)則提高了 6 倍!你可以輕松運行自己的
Go proxy,這可以讓你更好地控制構(gòu)建管道的穩(wěn)定性,并防止 VCS 關(guān)閉時的罕見情況。
如你所見,使用 Go module proxy 對人人都有好處。但是我們?nèi)绾问褂盟??如果你不想維護(hù)自己的 Go module proxy 怎么辦?這里還有許多替代方案。
如何使用 Go module proxy
要開始使用 Go module proxy,我們需要將 GOPROXY 環(huán)境變量設(shè)置為兼容的 Go module proxy。這有多種方式:
如果沒有設(shè)置
GOPROXY,將其設(shè)置為空或設(shè)置為direct,然后go get將直接到VCS(例如github.com)拉取代碼:GOPROXY=""
GOPROXY=directGOPROXY也可以設(shè)置為off,這意味著不允許使用網(wǎng)絡(luò)GOPROXY=off你可以開始使用公共
GOPROXY。你也可以選擇使用 Go 官方團(tuán)隊的GOPROXY(由 Google 運營)。更多信息可以在這里找到:https://proxy.golang.org/要開始使用它,你只需設(shè)置環(huán)境變量:
GOPROXY=https://proxy.golang.org其他可用的公共代理:
GOPROXY=https://goproxy.io
GOPROXY=https://goproxy.cn # proxy.golang.org 被墻了, 這個沒有你可以運行多個開源實現(xiàn)并自己托管??捎玫挠校?/p>
你既可以自己維護(hù),也可以通過公共互聯(lián)網(wǎng)或內(nèi)部網(wǎng)絡(luò)獲取相關(guān)服務(wù),看你自己的決定。
Athens:https://github.com/gomods/athensgoproxy:https://github.com/goproxy/goproxyTHUMBAI:https://thumbai.app/你可以購買商業(yè)產(chǎn)品:
Artifactory: https://jfrog.com/artifactory/你可以傳入
file:///路由。因為Go module proxy是響應(yīng) GET 請求(沒有查詢參數(shù))的 Web 服務(wù)器,所以任何文件系統(tǒng)中的文件夾都可以用作Go module proxy。
Go 1.13 的變化
在 Go v1.13 版本中, Go proxy 會有一些變化,我認(rèn)為應(yīng)該強調(diào)一下:
在 GOPROXY環(huán)境變量現(xiàn)在可以設(shè)置為逗號分隔的列表。它會在回到下一個路徑之前嘗試第一個代理。GOPROXY的默認(rèn)值為 https://proxy.golang.org,direct。設(shè)置direct后將忽略之后的所有內(nèi)容。這也意味著go get現(xiàn)在將默認(rèn)使用GOPROXY。如果你根本不想使用GOPROXY,則需要將其設(shè)置為off。新版本將引入了一個新的環(huán)境變量 GOPRIVATE,它包含以逗號分隔的 全局列表。這可用于繞過GOPROXY某些路徑的代理,尤其是公司中的私有模塊(例如:GOPRIVATE=*.internal.company.com)。
所有這些變化都表明 Go module proxy 將是 Go module 的核心和重要組成。
總結(jié)
無論使用公共網(wǎng)絡(luò),還是專用網(wǎng)絡(luò),GOPROXY 都有很多優(yōu)勢。這是一個很棒的工具,它可以和 go 命令無縫協(xié)作。鑒于它具有如此多的優(yōu)勢(安全,快速,存儲高效),明智的做法是在您的項目或組織中快速接受它。此外,在 Go v1.13 版本中,默認(rèn)情況下會啟用它,這是另一個受歡迎的步驟,它改善了 Go 中依賴項管理的現(xiàn)狀。
via: https://arslan.io/2019/08/02/why-you-should-use-a-go-module-proxy/
作者:Fatih Arslan[5]譯者:TomatoAres[6]校對:polaris1119[7]
本文由 GCTT[8] 原創(chuàng)編譯,Go 中文網(wǎng)[9] 榮譽推出,發(fā)布在 Go語言中文網(wǎng)公眾號,轉(zhuǎn)載請聯(lián)系我們授權(quán)。
參考資料
模塊感知模式: https://golang.org/cmd/go/#hdr-Modules_and_vendoring
[2]在 Travis CI 上使用 Go Module 和 vendor: https://arslan.io/2018/08/26/using-go-modules-with-vendor-support-on-travis-ci/
[3]記住左邊的傳奇故事: https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code/
[4]獲取單個文件: https://about.sourcegraph.com/go/gophercon-2019-go-module-proxy-life-of-a-query
[5]Fatih Arslan: https://arslan.io/
[6]TomatoAres: https://github.com/TomatoAres
[7]polaris1119: https://github.com/polaris1119
[8]GCTT: https://github.com/studygolang/GCTT
[9]Go 中文網(wǎng): https://studygolang.com/
文章的最后,插播一個福利
雙十一快到了,阿里云也開始搞活動了,剛好我這邊可以帶大家白嫖阿里云的服務(wù)器。
說白了就是大家 可以一分錢不花,就可以領(lǐng)到服務(wù)器,規(guī)格是 2c4g(2vcpu 4G內(nèi)存) 的機器。
有想參加的朋友,可以加我下微信,備注『服務(wù)器』,我統(tǒng)一拉群,帶大家一起薅羊毛。

???
