爲什麼要使用 Go module proxy
在看過 Go module
的簡介之後,我以爲我已經知道了這個功能我需要知道的一切。但是很快,我意識到並不是這樣。最近,人們開始提倡使用 Go module proxy
。在研究了利弊之後,我得出結論,這將是近年來 Go 語言 最重要
的變化之一。但爲什麼會這樣呢?是什麼讓 Go module
代理如此特別?
使用 Go modules
時,如果向乾淨的緩存的計算機上添加新依賴項或構建 Go module
,它將基於 go.mod
將下載(go get)所有依賴項,並將其緩存以供進一步操作。你也可以使用 -mod=vendor
參數構建 vendor
文件夾,來繞過緩存,以及後邊使用這些下載的依賴。
但以上兩種方法都不完美,我們應該可以做得更好。
本文是 Go 語言中文網組織的 GCTT 翻譯,發佈在 Go 語言中文網公衆號,轉載請聯繫我們授權。
(不)使用 vendor 文件夾的問題
使用 vendor 文件夾的問題
-
在模塊感知模式 [1] 開啓時,使用
go
命令,默認不再使用vendor
文件夾。如果你不附加-mod=vendor
參數,這個文件夾將不會被啓用。這通常引發問題,並導致必須使用其他陳舊的方案來支持老 Go 版本程序(請參考:在 Travis CI 上使用 Go Module 和 vendor[2]) -
vendor
文件夾,會佔用大量磁盤空間,特別是在比較大的單體應用中。這也將增加代碼倉庫的克隆時間。可能你認爲只用克隆一次,實際卻不是這樣。CI/CD 在每次事件(比如:pull request
)都會觸發克隆代碼。因此,這將長期導致更長的編譯時間,並將影響團隊中的每個人。 -
使用新的依賴通常會導致難以審覈代碼的變化。大多數情況下,你必須將依賴項與實際的業務邏輯捆綁在一起,這導致難以進行更改。
不使用的 vendor 的問題
-
go
程序將去源碼倉庫下載這些依賴。總是存在任何依賴可能在將來消失的風險(記住左邊的傳奇故事 [3])。 -
版本管理系統(例如
github.com
)可能關閉。在這種情況下,你將無法再次構建項目。 -
有些公司不希望內網接入外網,此時,沒有
vendor
文件夾,我們將無法使用。 -
假設發佈的依賴
tag
是v1.3.0
,並且已經go get
獲取它到本地緩存。此時,依賴的所有者可以通過推送具有相同tag
的惡意內容來破壞代碼庫。如果在具有乾淨緩存的計算機上重建Go module
,它現在將使用被破壞的包。爲了防止這種情況,需要將go.sum
和go.mod
文件放在一起 。 -
一些依賴使用不只使用
git
作爲版本管理系統
,還有可能使用hg(Mercurial)
,bzr(Bazaar
) 或svn(Subversion)
。而你的機器沒有安裝裝或者 Dockerfile 沒有配置這些工具,這都將引發問題。 -
go get
需要獲取go.mod
列出的每個依賴項的源代碼來解決遞歸依賴(需相應的go.mod
文件)。因爲它意味着必須下載(例如git clone
)每個存儲庫以獲取單個文件 [4],這顯然會使得整個構建過程變慢。
那我們怎麼解決這些問題呢?
使用 Go module proxy 的好處
默認情況下, go
命令會直接從版本管理系統下載代碼。GOPROXY
環境變量允許在下載源的進一步控制。配置該環境變量後,go
命令可以使用 Go module proxy
。
設置環境變量 GOPROXY
開啓 Go module proxy
後,將解決上邊提到的所有問題。
-
Go module proxy
默認永久緩存所有依賴(不可變存儲)。這意味着,不必再使用 vendor 文件夾。 -
拋棄
vendor
文件夾,它將不會再消耗代碼庫的空間。 -
因爲依賴項存儲在
不可變存儲
中,即使依賴項從網上消失,你的代碼也會受到保護。 -
一旦
Go module
(依賴) 存儲在Go proxy
中,就無法覆蓋或刪除它。這可以保護你免受可能使用相同版本注入惡意代碼的攻擊。 -
你不再需要任何 VSC 工具來下載依賴項,因爲依賴項是通過 HTTP 獲取的(
Go proxy
在後臺使用 HTTP)。 -
下載和構建
Go module
的速度要快得多,因爲Go proxy
通過 HTTP 獨立提供源代碼(.zip
存檔)go.mod
。與從 VCS 獲取相比,由於更少的開銷,這使得下載花費更少的時間。相比之前它必須獲取整個存儲庫,解決依賴關係也更快,因爲go.mod
可以獨立獲取。Go 官方團隊對它進行了測試,他們看到快速網絡上的速度提高了 3 倍,而慢速網絡則提高了 6 倍! -
你可以輕鬆運行自己的
Go proxy
,這可以讓你更好地控制構建管道的穩定性,並防止 VCS 關閉時的罕見情況。
如你所見,使用 Go module proxy
對人人都有好處。但是我們如何使用它呢?如果你不想維護自己的 Go module proxy
怎麼辦?這裏還有許多替代方案。
如何使用 Go module proxy
要開始使用 Go module proxy
,我們需要將 GOPROXY
環境變量設置爲兼容的 Go module proxy
。這有多種方式:
-
如果沒有設置
GOPROXY
,將其設置爲空或設置爲direct
,然後go get
將直接到VCS
(例如github.com
)拉取代碼:GOPROXY="" GOPROXY=direct
GOPROXY
也可以設置爲off
,這意味着不允許使用網絡GOPROXY=off
-
你可以開始使用公共
GOPROXY
。你也可以選擇使用 Go 官方團隊的GOPROXY
(由 Google 運營)。更多信息可以在這裏找到:https://proxy.golang.org/要開始使用它,你只需設置環境變量:
GOPROXY=https://proxy.golang.org
其他可用的公共代理:
GOPROXY=https://goproxy.io GOPROXY=https://goproxy.cn # proxy.golang.org 被牆了, 這個沒有
-
你可以運行多個開源實現並自己託管。可用的有:
你既可以自己維護,也可以通過公共互聯網或內部網絡獲取相關服務,看你自己的決定。
-
Athens
:https://github.com/gomods/athens -
goproxy
:https://github.com/goproxy/goproxy -
THUMBAI
:https://thumbai.app/ -
你可以購買商業產品:
Artifactory
: https://jfrog.com/artifactory/ -
你可以傳入
file:///
路由。因爲Go module proxy
是響應 GET 請求(沒有查詢參數)的 Web 服務器,所以任何文件系統中的文件夾都可以用作Go module proxy
。
Go 1.13 的變化
在 Go v1.13 版本中, Go proxy
會有一些變化,我認爲應該強調一下:
-
在
GOPROXY
環境變量現在可以設置爲逗號分隔的列表。它會在回到下一個路徑之前嘗試第一個代理。 -
GOPROXY
的默認值爲 https://proxy.golang.org,direct。設置direct
後將忽略之後的所有內容。這也意味着go get
現在將默認使用GOPROXY
。如果你根本不想使用GOPROXY
,則需要將其設置爲off
。 -
新版本將引入了一個新的環境變量
GOPRIVATE
,它包含以逗號分隔的 全局列表。這可用於繞過GOPROXY
某些路徑的代理,尤其是公司中的私有模塊(例如:GOPRIVATE=*.internal.company.com
)。
所有這些變化都表明 Go module proxy
將是 Go module
的核心和重要組成。
總結
無論使用公共網絡,還是專用網絡,GOPROXY
都有很多優勢。這是一個很棒的工具,它可以和 go
命令無縫協作。鑑於它具有如此多的優勢(安全,快速,存儲高效),明智的做法是在您的項目或組織中快速接受它。此外,在 Go v1.13
版本中,默認情況下會啓用它,這是另一個受歡迎的步驟,它改善了 Go 中依賴項管理的現狀。
via: https://arslan.io/2019/08/02/why-you-should-use-a-go-module-proxy/
作者:Fatih Arslan[5] 譯者:TomatoAres[6] 校對:polaris1119[7]
本文由 GCTT[8] 原創編譯,Go 中文網 [9] 榮譽推出,發佈在 Go 語言中文網公衆號,轉載請聯繫我們授權。
參考資料
[1]
模塊感知模式: 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 中文網: https://studygolang.com/
福利
我爲大家整理了一份從入門到進階的 Go 學習資料禮包,包含學習建議:入門看什麼,進階看什麼。關注公衆號 「polarisxu」,回覆 ebook 獲取;還可以回覆「進羣」,和數萬 Gopher 交流學習。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/2XfBNSbllD4AzSd3yAihdg