为什么应该使用 Go module proxy

简介: 为什么应该使用 Go module proxy

自从 Go v1.11 版本之后 Go modules 成了官方的包管理方式,与此同时还有一个 Go module proxy ,它到底是个什么东西?顾名思义,其实就是个代理,所有的模块和依赖库都可以从这个代理上下载。

Go module proxy 到底有何特别之处?我们为什么应该使用它?


使用 Go modules ,如果你添加了新的依赖项或者构建了自己的模块,那么它将会基于 go.mod 文件下载( go get )所有的依赖项并且缓存起来。你可以使用 vendor 目录(将依赖项置于此目录下)以绕过缓存,同时通过 -mod=vendor 标记就可以指定使用 vendor 目录下的依赖项进行构建。然而这么做并不好。


01


使用 vendor 目录有哪些问题:

  • vendor 目录不再是 go 命令的默认项,你必须通过 -mode=vendor 指定。
  • vendor 目录占用了太多的空间,克隆时也会花费大量时间,尤其是 CI/CD 的效率很低。
  • vendor 更新依赖项很难 review ,而依赖项又常常与业务逻辑紧密关联,我们很难去回顾到底发生了哪些变化。


那么不使用 vendor 目录又会如何呢?这时我们又将面临如下问题:

  • go 将尝试从源库下载依赖项,但是源库存在被删除的风险。
  • VCS(版本控制系统,如 github.com)可能会挂掉或无法使用,这时你也无法构建你的项目。
  • 有些公司的内部网络对外隔离,不使用 vendor 目录对他们来说也不行。
  • 依赖库的所有者可能通过推送相同版本的恶意内容进行破坏。要防止这种情况发生,需要将 go.sumgo.mod 文件一起存储。
  • 某些依赖项可能会使用与 git 不同的 VCS ,如 hg(Mercurial)、bzr(Bazaar)、svn(Subversion),因此你不得不安装这些其他的工具,很烦。
  • go get 需要获取 go.mod 中每个依赖项的源代码以解决传递依赖,这显著减慢了整个构建过程,因为它必须下载(git clone)每个存储库以获取单个文件。


如何解决上述这一系列的问题?答案是使用 Go module proxy


02


默认情况下,go 命令直接从 VCS 下载模块。环境变量 GOPROXY 指定使用 Go module proxy 以进一步控制下载源。


通过设置 GOPROXY ,你将会解决上述的所有问题:

  • Go module proxy 默认缓存并永久存储所有依赖项(不可变存储),你不再需要 vendor 目录。
  • 摆脱了 vendor 目录意味着项目不再占用 repository 空间,提高了效率。
  • 由于依赖库以不可变的形式存储在代理中,即使源库删除,代理中的库也不会被删除,这保障依赖库的使用者。
  • 一旦模块被存储在 Go proxy 中,就无法被覆盖或者删除,换句话说使用相同版本注入恶意代码的行为攻击将不再奏效。
  • 你不再需要任何 VCS 工具来下载依赖项,因为你只需要通过 http 与 Go proxy 建立连接。
  • 下载和构建将会快很多,官方团队测试的结果是快了三到六倍。
  • 你可以轻松管理自己的代理,这可以让你更好的控制构建管道的稳定性。


综上所述,你绝对应该使用 Go module proxy


03


如何使用 Go module proxy


你需要设置环境变量 GOPROXY


1、如果 GOPROXY 未设置、为空、或者设置为 direct ,则 go get 将直连 VCS (如 github.com):

GOPROXY=""
GOPROXY=direct

如果设置为 off ,则表示不允许使用网络:

GOPROXY=off

2、你可以使用任意一个公共的代理 :

GOPROXY=https://proxy.golang.org # 谷歌官方,大陆地区被墙了
GOPROXY=https://goproxy.io # 个人开源
GOPROXY=https://goproxy.cn # 大陆地区建议使用,七牛云托管

3、你可以基于开源方案实现本地部署:

通过这种方式你可以构建一个公司的内部代理,与外网隔离。


4、你可以购买商业产品:


5、你可以使用 file:/// URL ,文件系统路径也是可以直接使用的。
04


Go v1.13 版本的相关更改:

  • GOPROXY 可以设置为以逗号分隔的列表,如果某个地址失败将会依次尝试后面的地址。
  • GOPROXY 默认启动,默认值将会是 https://proxy.golang.org,direct 。direct 之后的地址将会被忽略。
  • GOPRIVATE 环境变量将会被推出,用于绕过 GOPROXY 中的特定路径,尤其是公司中的私有模块。


05


相关资料:https://github.com/golang/go/wiki/Moduleshttps://proxy.golang.org/

目录
相关文章
|
5月前
|
存储 Linux Go
GO 项目依赖管理:go module总结
GO 项目依赖管理:go module总结
91 0
|
2月前
|
存储 缓存 算法
go vendor module
go vendor module
|
3月前
|
存储 Go
Golang语言基于go module方式管理包(package)
这篇文章详细介绍了Golang语言中基于go module方式管理包(package)的方法,包括Go Modules的发展历史、go module的介绍、常用命令和操作步骤,并通过代码示例展示了如何初始化项目、引入第三方包、组织代码结构以及运行测试。
69 3
|
4月前
|
IDE Go 开发工具
Go Error module declares its path as but was required as解决方案
文章提供了一个解决方案,用于处理在Go工程中将依赖的仓库从A更换为B(即使它们完全相同)时遇到的路径声明错误,建议通过发布新版本来解决此问题。
103 0
go: finding module for package
go: finding module for package
121 0
|
缓存 IDE Go
记一次go module的坑
事情是这样的,因为小马本次要写一个go项目。但是因为一些权限问题,一些依赖包在内网小马获取不到,于是只能求助大大。大大给的策略就是他先把所有的依赖包go mod,然后go mod vendor迁移到项目目录vendor下进行本地依赖载入即可,也就是使用 go build -mod=vendor来编译即可。一切似乎看起来还是那么完美。然后正要起飞,直接翻车,现场如下。【这里插播一条发现,就是使用golang IDE go build 和使用命令行go build 的区别在于前者不会生成.exe文件】
449 0
记一次go module的坑
|
Go
【golang】解决:missing go.sum entry for module providing package
【golang】解决:missing go.sum entry for module providing package
1685 0
go module的使用:
go module的使用:
135 0
|
存储 算法 Go
Go的Module不会,证明你实力就那样吧
Go的Module不会,证明你实力就那样吧
|
Go API 开发工具
Go Module 语义化版本规范
Go Module 语义化版本规范
137 0