go modules
关于go的第三方包的依赖管理,项目小的时候还不觉得多麻烦,当项目越来越大,引入的第三方包越来越多的时候,这个时候问题就很头痛了,golang官方建议是一个项目一个GOPATH,但是鉴于很多人都不这么做(我也不这么做,因为麻烦),于是在go1.11的时候推出了这个go modules来解决依赖管理的问题。
使用
由于这个go modules和GOPATH可能是天生不和,如果配置了GOPATH的话,这个go modules是默认不开启的。
开启也很简单,只要在命令行中键入下面命令就行了。
export GO111MODULE=on # 开启GoModule特性
1
不过这种是一次性的,重启之后就会消失,所以可以在环境信息文件/etc/profile的最后面添加上一行
export GO111MODULE=on
1
使用命令source /etc/profile让其生效。
GO111MODULE解释, 当为on时则使用Go Modules,go 会忽略 $GOPATH和 vendor文件夹,只根据go.mod下载依赖。当为 off时则不适用新特性 Go Modules支持,它会查找 vendor目录和 $GOPATH来查找依赖关系,也就是继续使用“GOPATH模式”。当为 auto时或未设置时则根据当前项目目录下是否存在 go.mod文件或 $GOPATH/src之外并且其本身包含go.mod文件时才会使用新特性 Go Modules模式,并且auto为 GO111MODULE的默认值。
goproxy
关于goproxy,简单来说就是一个代理,让我们更方便的下载哪些由于墙的原因而导致无法下载的第三方包,比如golang.org/x/下的包,虽然也有各种方法解决,但是,如果是你在拉取第三方包的时候,而这个包又依赖于golang.org/x/下的包,你本地又恰恰没有,当然不嫌麻烦的话,也可以先拉取golang.org/x/下的包,再拉取第三方包。
这个goproxy强大地方就在于代理,而它官网是这样介绍自己的【A Global Proxy for Go Modules】,就是这么强大,全球代理,让世界没有难下的包
使用
一般来说,goproxy是和go modules配合使用的。
首先要确保go modules是开启的,如果没有开启可以在命令行键入下面命令即可
export GO111MODULE=on
export GOPROXY=https://goproxy.io
不过这种是一次性的,重启之后就会消失,所以可以在环境信息文件/etc/profile的最后面添加上下面这两行
export GO111MODULE=on
export GOPROXY=https://goproxy.io
最后使用source /etc/profile让其生效。
go.mod 和 go.sum介绍
go.mod是Go项目的依赖描述文件,该文件主要用来描述两个事情:
当前项目名(module)是什么。每个项目都应该设置一个名称,当前项目中的包(package)可以使用该名称进行相互调用。
当前项目依赖的第三方包名称。项目运行时会自动分析项目中的代码依赖,生成go.sum依赖分析结果,随后go编译器会去下载这些第三方包,然后再编译运行。
go.sum依赖分析文件,记录每个依赖库的版本和哈希值
一般情况下,go.sum应当被添加到版本管理中随着go.mod文件一起提交。
go modules常用命令
go mod init: 初始化modules
go mod download: 下载依赖的module到本地cache
go mod edit: 编辑go.mod文件,选项有-json、-require和-exclude,可以使用帮助go help mod edit
go mod graph: 以文本模式打印模块需求图
go mod tidy: 检查,删除错误或者不使用的modules,以及添加缺失的模块
go mod vendor: 生成vendor目录,将依赖复制到vendor目录下面
go mod verify: 验证依赖是否正确
go mod why: 解释为什么需要依赖
go list -m: 查看主模块的路径
go list -m -f=\{\{.Dir\}\}: 查看主模块的根目录
go list -m all: 查看当前的依赖和版本信息 goland ide下使用go modules 在goland下,是推荐使用goland配置vgo来快速使用go modules的。而vgo是基于Go Modules规范的包管理工具,同官方的go mod命令工具类似。
关于在goland下要使用go modules,本菜鸡实在绕了很久,由于go modules出来也不久,虽说网上也有部分博客在教怎么用goland去用go modules,但是有一点很重要,在大部分博客中也没指出,就是关于goland的版本是否支持go modules这个新功能,这个问题实在是有点坑,相信不少人用的是goland2017或goland2018.1.3版本,这就有个问题,这些旧版本不支持快速使用go modules来包依赖管理,所以这里建议使用goland2019.1这个比较新的版本
Go 1.13 的发布为 Go 带来了不少变化(详见:https://golang.org/doc/go1.13 ),有些变化可能是开发者无法直接感觉到的,但有些又是和开发者日常开发息息相关的。其中,Go modules 的扶正就是这次 Go 1.13 发布中开发者能直接感觉到的最大变化。
Go modules 最早发布于 Go 1.11,经过两个版本的更新后,它作为依赖管理解决方案来说现在已经变得光彩夺目。随着 Go modules 一起被发布的还有一个叫做 Module proxy protocol 的协议,通过它我们可以搭建 Go 模块代理,最后交由 GOPROXY 环境变量以指引 go 命令后续在抓取模块时的途径。
对于咱们中国的开发者来说,一个优秀的 Go 模块代理可以帮助我们解决很多问题。比如 Go 语言中最知名的 golang.org/x/… 模块在中国大陆是无法访问到的,以前我们会用很多其他的办法来抓取他们,而若依靠一个可以访问到它们的模块代理,那么将事半功倍。
更因为 Go 1.13 将 GOPROXY 默认成了中国大陆无法访问的 https://proxy.golang.org ,所以我们中国的开发者从今以后必须先修改 GOPROXY 才能正常使用 go 来开发应用了。为此,我们联合中国备受信赖的云服务提供商七牛云专门为咱们中国开发者而打造了一个 Go 模块代理:goproxy.cn。
什么是 goproxy.cn?
goproxy.cn 是目前中国最可靠的 Go 模块代理,这个如果有人存在质疑可以一一测试比对列表中所有能在国内访问的代理。对于那个和 goproxy.cn 域名比较相近的 goproxy.io,我之前已经发表过一篇实测文章(详见:https://studygolang.com/topic… )。
goproxy.cn 还是是一个非营利性项目,目标是为中国和世界上其他地方的 Gopher 们提供一个免费的、可靠的、持续在线的且经过 CDN 加速的模块代理。正因为 goproxy.cn 由中国 Go 语言第一个吃螃蟹的大公司七牛云运行,所以它的稳定性和运行速度都是毋庸置疑的,如果你的网络环境本身不差的情况下,它能快到让你不可思议,比 go get 传统的抓取方式快上了不止几倍。
有人可能会问阿里云的也很快,而且阿里云也是大厂,为什么不用阿里云的模块代理(mirrors.aliyun.com/goproxy)。我只能说,当我在使用阿里云的代理做初始化 github.com/kubernetes/kubernetes 的测试时,出现了大量的 404 错误以至于初始化操作无法完成……而且它还不支持代理 GOSUMDB 的默认值也就是 sum.golang.org,因此你还得手动修改 GOSUMDB 才能够正常使用 go。在速度旗鼓相当的情况下,为什么不考虑直接使用一个更稳定、高可用的呢?而且毕竟 goproxy.cn 这个域名也很好记不是嘛~你只用记住 goproxy 和 .cn,就没了。
Q&A
问:在 Go 1.13 中如何使用 goproxy.cn?
答:一条 go env -w GOPROXY=https://goproxy.cn,direct 即可。之所以在后面拼接一个 ,direct,是因为通过这样做我们可以在一定程度上解决私有库的问题(当然, goproxy.cn 无法访问你的私有库)。这个 GOPROXY 设定的工作原理是:当 go 在抓取目标模块时,若遇见了 404 错误,那么就回退到 direct 也就是直接去目标模块的源头(比如 GitHub) 去抓取。而恰好,GitHub 等类似的代码托管网站的原则基本都是“你无权访问的你来说就是不存在的”,所以我才说通过这样设定可以在一定程度上解决私有库无法通过模块代理访问的问题。
问:在 Go 1.13 之前如何使用 goproxy.cn?
答:同样也是设置环境变量即可,但是得你手动配置,而且还不能使用上述的那个 ,direct 后缀,因为那是 Go 1.13 刚加的特性。详细配置方法可以参见 goproxy.cn 的 README 文件。
问:在 Go 1.13 中如何解决私有库问题?
答:在上述的回答中我有提到可以通过 Go 1.13 为 GOPROXY 新增的“代理列表”特性来为 goproxy.cn 做一个 fallback 选项,也就是 direct(直接从目标模块源头抓取),它就是解决私有库的一种途径,但并不是一个完美的解决方案。为此,Go 1.13 还推出了一个 GONOPROXY 环境变量(详见: https://golang.org/cmd/go/#hdr-Environment_variables ),通过设置它我们可以实现控制让哪些 module path 忽略 GOPROXY,无脑回源。比如 GONOPROXY=*.corp.example.com 就意味着 go 在抓取所有 corp.example.com 的三级子域名下的所有模块时都将忽略 GOPROXY 设置直接回源到目标模块的原地址。
问:在 Go 1.13 中如何防止从公共模块代理中抓取的模块被篡改?
答:Go 1.13 新推出了一个 GOSUMDB(默认值是 sum.golang.org ,国内无法访问),就是为了实现这个目的,它的值是一个可信任的模块校验和数据库地址,通过指定它,go 将在抓取完模块时(无论是否是经过模块代理抓取的)对所有模块进行哈希校验,只有和校验和数据库中现有的一致时才算抓取成功。同 GONOPROXY 一样,Go 1.13 也为 GOSUMDB 配对发布了一个 GONOSUMDB,用法一致,作用是控制 go 应该忽略校验哪些 module path 下的模块。
问:分别设置 GONOPROXY 和 GONOSUMDB 很麻烦,有没有更好的办法?
答:有,Go 1.13 为了方便管理私有库规则,还推出了一个 GOPRIVATE,可以简单地理解成通过设置它就同时设置了 GONOPROXY 和 GONOSUMDB。
go出现错误 go: unknown subcommand “mod”
版本太低了,只有1.13版本以上才支持
简介
go module公共代理仓库,代理并缓存go模块。你可以利用该代理来避免DNS污染导致的模块拉取缓慢或失败的问题,加速你的构建
地址
https://mirrors.aliyun.com/goproxy/
使用帮助
1.使用go1.11以上版本并开启go module机制
2.导出GOPROXY环境变量
export GOPROXY=https://mirrors.aliyun.com/goproxy/
https://gocn.vip/topics/10280