为什么要使用 Go module proxy
本文是 Go语言中文网组织的 GCTT 翻译,发布在 Go语言中文网公众号,转载请前往联系授权。
在看过 Go module
的简介之后,我以为我已经知道了这个功能我需要知道的一切。但是很快,我意识到并不是这样。最近,人们开始提倡使用 Go module proxy
。在研究了利弊之后,我得出结论,这将是近年来 Go 语言 最重要
的变化之一。但为什么会这样呢?是什么让 Go module
代理如此特别?
使用 Go modules
时,如果向干净的缓存的计算机上添加新依赖项或构建 Go module
,它将基于 go.mod
将下载(go get)所有依赖项,并将其缓存以供进一步操作。你也可以使用 -mod=vendor
参数构建 vendor
文件夹,来绕过缓存,以及后边使用这些下载的依赖。
但以上两种方法都不完美,我们应该可以做得更好。
(不)使用 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=directGOPROXY
也可以设置为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/athensgoproxy
:https://github.com/goproxy/goproxyTHUMBAI
: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语言中文网公众号,转载请联系我们授权。
参考资料
模块感知模式: 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/
文章的最后,插播一个福利
双十一快到了,阿里云也开始搞活动了,刚好我这边可以带大家白嫖阿里云的服务器。
说白了就是大家 可以一分钱不花,就可以领到服务器,规格是 2c4g(2vcpu 4G内存) 的机器。
有想参加的朋友,可以加我下微信,备注『服务器』,我统一拉群,带大家一起薅羊毛。
⬇⬇⬇