关于加速 Go Modules 的下载,有三个选项:Module Mirror(模块镜像)、Module Index(模块索引)和 Module Checksum Database(模块校验和数据库)

首先

Go的开发团队在《2019年Go模块计划》一文中,于2018年底公开了关于2019年度Go模块的计划。

在博客中,首先讲解了从Go 1.11开始提供的Go Modules,然后强调了在Go Modules中实现利用go get进行的操作的重要性,并且提到了分散管理代码所允许的缺点,接着还记录了Go团队在Go Modules方面的计划。

本次主题是关于Go模块的计划介绍,最近开始提供阿尔法测试的 Module Mirror、Module Index和Module Checksum Database,我想总结一下。

镜像模块(https://proxy.golang.org)

Module Mirror 是由 Google 提供的速度快且可靠的 Module5 缓存代理。当 Module Mirror 收到请求尚未缓存的 Module 时,它会从公开的源服务器获取 Module 并进行缓存。

通过使用这个 Module 镜像,您可以快速下载 Module,即使 GitHub 或其他源服务器宕机或 URL 发生变化,也可以下载指定的 Module。

那么我们来解释一下Module Mirror的用法。
在Go Modules中,引入了Module Proxy(GOPROXY)的概念,使得可以指定任意服务器而不仅限于原始服务器来获取Module。通过指定Module Mirror作为Module Proxy,用户可以享受到以下好处。

GOPROXY=https://proxy.golang.org

我想比较一下从原始服务器获取模块和从模块镜像获取模块的时间。

# Go Modules を利用しているプロダクトを Clone してくる
$ git clone https://github.com/spiffe/spire.git
$ cd spire

# Module Mirror を使わずに Module をダウンロードする
$ time GO111MODULE=on go mod download
...
real    2m29.631s
user    2m32.240s
sys 1m5.320s

# Module Mirror を使って Module をダウンロードする
$ GOPROXY=https://proxy.golang.org GO111MODULE=on go mod download
...
real    0m36.504s
user    0m21.410s
sys 0m16.240s

通过使用Mirror Module,我们可以看出可以加快模块的下载速度。非常快!

あり/なし所要時間Mirror Module なし約2分半Mirror Module あり約30秒

模块校验数据库( https://sum.golang.org )

这是一个存储了用于验证模块的校验和的数据库。go.sum是在多个服务器上公开的各种模块版本提供的镜像。

通过比较从模块校验数据库获取的校验和与下载模块的校验和,可以验证代码的可靠性。

如果举几个例子的话,通过向https://sum.golang.org/latest发送请求,可以获取Module Checksum Database的树大小和最新日志的哈希值等信息,或者通过指定https://sum.golang.org/lookup/@来获取目标Module的信息,例如https://sum.golang.org/lookup/github.com/kubernetes/kubernetes@v1.15.0。我认为利用这些信息,在Go命令内部进行已下载Module的可信验证。

关于Module Checksum Database的使用方式,如果你想要使用Module Mirror并将GOPROXY设置为https://proxy.golang.org的话,那么Module Checksum Database将被自动使用。如果你希望明确设置的话,只需声明GOSUMDB=sum.golang.org即可。

值得一提的是,在 Go 1.12 之前,可以使用 gosumcheck 命令,手动使用模块校验和数据库进行检查。如果您感兴趣,请尝试一下。

go get golang.org/x/mod/gosumcheck
gosumcheck /path/to/go.sum

虽然这可能有点多余,但最初它似乎叫做”Go notary”,但为了避免与CNCF项目的”Notary”混淆,现在改为了目前的命名。

模块索引(https://index.golang.org)

您可以通过 https://index.golang.org/index 从中获取新模块版本的订阅源。订阅源按年份顺序排序,每个模块都以带有以下键的 JSON 格式构成。

Key概要PathModule 名VersionModule のバージョンTimestampModule Mirror( proxy.golang.org )で最初にキャッシュされた時刻

还有以下参数可供支持。

パラメータ概要例since指定した Timestamp 以降のフィードを取得できるhttps://index.golang.org/index?since=2019-07-01T17:00:00%2b09:00 (JST で 2019-07-01T17:00:00+09:00 を指定している)limit指定したサイズのフィードを取得できるhttps://index.golang.org/index?limit=10

通过使用它,可以发现新的模块等等。godoc.org 也提到了以后可能会参考这个(指代的是”これ”)的事情。

悬念的问题

個人對於Module Mirror的擔憂是,如果不小心使用,私有模塊會被緩存在Module Mirror上嗎?因此,在使用私有模塊的產品中啟用Module Mirror有一些不安。

我只需要一個選項,原文翻譯如下:
如果使用 GOPRIVATE、GONOPROXY、GONOSUMDB 等,應該就可以了吧?我對這些的理解還很有限,所以如果以後能夠進一步調查,我會追加註記。

最后

本次介绍了Module Mirror、Module Index和Module Checksum Database。目前它们还不稳定,可能存在不稳定性和错误等问题,但我认为它们还是有价值的。您可以根据正在开发的产品需求来决定是否采用。

根据 Go 1.13 版本及更高版本的 Go 命令,模块镜像和模块校验数据库的使用将默认启用( https://github.com/golang/go/commit/f8a5ba2a3880f4782d8250fd26dde2baa3990afa )。因此,我希望能够继续跟进这些变化。

结束了。

请参考「Go Modules 自体的说明」以及「Go1.12 中的 Modules 相关变更 – My External Storage」,因为这两篇文章非常易于理解。在原始设计中,go get 的一个重要方面是不同于中央集权的代码管理工具如 Node 的 NPM 或 Java 的 Maven,而是一种非中央集权(分散式)的代码管理方式,任何人都可以在自己喜欢的服务器上发布自己的代码,任何人都可以从喜欢的服务器导入代码。重大的分散化依赖关系问题包括很难找到已经发布的 Go 包以及无法保证 Go 包的提供持续性。如果您对细节感到好奇,建议参考原始博客。在官方文档中定义了模块是一组相关的 Go 包,它们作为一个单一单元进行版本化。请参考 go help goproxy 了解如何使用。虽然本次案例中使用了 Go Modules 来克隆产品,但也可以简单地通过 go get 进行比较。更多详细信息请参考 Proposal: Secure the Public Go Module Ecosystem。
广告
将在 10 秒后关闭
bannerAds