goproxy

https://summer4.dev/2019/10/%E8%AF%91%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%BF%E7%94%A8-go-%E6%A8%A1%E5%9D%97%E4%BB%A3%E7%90%86/
在Go模块中,如果你添加了新的依赖项或者在没有缓存过的新机器上构建Go模块,则它将(go get)下载go.mod中的所有依赖项,并将其缓存以用于进一步的操作。可以通过使用vendor/文件夹并编译时携带-mod=vendor参数来绕过缓存(以及下载依赖项)。



但是这两种方法都不甚完美,我们有更好的方案。

如果使用vendor/文件夹,有以下缺点:



vendor/默认情况下,该go命令不再使用该文件夹(在模块感知模式下)。如果你不使用-mod=vendor参数,它将不会发挥作用。这烦人的问题驱使其他hacky解决方案来支持Go的旧版本(请参阅:在Travis CI中使用 go modules 并启用 vendor支持)
vendor/文件夹,特别是对于大型项目,会占用大量空间。这增加了clone仓库所花费的时间。即使您认为clone仅执行一次,但大多数情况下并非如此。CI / CD系统通常会为每个触发器(例如“pull request”)clone仓库。因此,从长远来看,这将导致更长的build时间并影响团队中的每个人。
添加新的依赖项通常会导致改变代码评审的困难程度。在大多数情况下,您必须将依赖项与实际的业务逻辑捆绑在一起,这使得难以进行改动。
可能你想说,那我跳过vendor/文件夹不就没事了?这也无济于事,你必须解决以下问题:



go会尝试从原先的仓库下载依赖项。但是任何依赖关系都可能在哪天就消失了(例如 left-pad包被删惨案)。



VCS可能已关闭(例如github.com)。在这种情况下,你的项目跑不起来了。



有些公司不希望内部网络外部有任何传出连接。因此,删除 vendor/文件夹对他们来说是不行的。



假设一个依赖项被发布为v1.3.0并且你go get拉取到本地缓存下来。然而,一旦依赖项的所有者通过推送具有同样 tag的恶意内容来破坏仓库,假如你的在一天没有拉取过缓存的赶紧的计算机上重新build的,那你这次就拉到了这个有恶意内容的版本。为了防止这种情况,您需要将go.sum文件与文件一起go.mod存储。



有些依赖使用的是git之外的VCS,例如hg(Mercurial),bzr(Bazaar)或svn(Subversion)。并非所有这些工具都安装在你的电脑(或Dockerfile)上,这常常导致失败。



go get需要获取go.mod列出的每个依赖项的源代码以解决递归依赖项(这需要每个依赖项自己的go.mod文件)。这极大地减慢了整个构建过程的速度,因为这意味着它必须下载(例如git clone)每个存储库以获取单个文件。



我们如何改善这种情况?



使用Go模块代理的优点
img



默认情况下,go命令直接从VCS下载模块。GOPROXY环境变量允许在下载源的进一步控制。设置这个环境变量,就会开启goGo模块代理。



通过将GOPROXY环境变量设置为Go模块代理,可以克服上面列出的所有缺点:



默认情况下,Go模块代理是缓存和永久存储所有依赖项(在不可变存储中)。这意味着您不再需要使用任何vendor/文件夹。
摆脱vendor/文件夹意味着您的项目将不会在存储库中占用空间。
因为依赖项存储在不可变的存储中,所以即使依赖项从Internet上消失了,也可以免受影响。
一旦将Go模块存储在Go代理中,就无法覆盖或删除它。这可以让我们的代码免受有人在相同版本上注入恶意代码的攻击。
不再需要任何VSC工具来下载依赖项,因为依赖项是通过HTTP提供的(Go proxy在后台使用HTTP)。
下载和构建Go模块的速度明显更快,因为Go代理通过HTTP单独提供了源代码(.zip存档)go.mod。与从VCS进行提取相比,这导致下载花费更少的时间和更快的时间(由于更少的开销)。解决依赖关系的速度也更快,因为go.mod可以独立获取(而之前必须获取整个存储库)。Go团队对其进行了测试,他们发现在带宽高的网络环境下速度提高了3倍,带宽差的网络环境下速度提高了6倍!
可以轻松地运行自己的Go代理,这可以让我们更好地控制构建pipeline的稳定性,因为不依赖版本库,可以防止VCS停机这种罕见情况。
如你所见,使用Go模块代理简直完美。但是我们如何使用它呢?如果你不想维护自己的Go模块代理怎么办?让我们研究许多替代选择。



如何使用Go模块代理
要开始使用Go模块代理,我们需要将GOPROXY环境变量设置为兼容的Go module proxy。有多种方法:



1。)如果GOPROXY没有设置,空或设置为direct,go get会直接从VCS(例如github.com)的下载依赖:



GOPROXY=””
GOPROXY=direct
也可以将其设置为off,这表示不访问任何的网络。



GOPROXY=off
2.)您可以开始使用公共Go代理。您的选择之一是使用Go小组(由Google维护)中的Go代理。可以在这里找到更多信息:https : //proxy.golang.org/



要开始使用它,您只需设置环境变量:



GOPROXY=https://proxy.golang.org
其他公共代理有:



GOPROXY=https://goproxy.io
GOPROXY=https://goproxy.cn # proxy.golang.org 被墙了, 可以使用这个代替
3.)也可以运行多个开源实现并自己托管。例如:



Athens:https : //github.com/gomods/athens
goproxy:https://github.com/goproxy/goproxy
THUMBAI:https : //thumbai.app/
这需要自己来维护。但可自己决定这个代理是通过公共互联网还是只能内部网络访问。



4.)可以购买商业产品:



Artifactory:https://jfrog.com/artifactory/
5.)甚至可以传递一个file:///URL。由于Go模块代理是响应GET请求(没有查询参数)的Web服务器,因此任何文件系统中的文件夹也可以用作Go模块代理。



即将进行的Go v1.13更改(已经发布)
Go v1.13版本中的Go proxy会有一些变化,我认为应该强调:



在GOPROXY环境变量现在可以设置为逗号分隔的列表。在回退到下一个路径之前,它将尝试第一个代理。



默认值GOPROXY会https://proxy.golang.org,direct。direct token后的所有内容都会被忽略。这也意味着go get现在将默认使用GOPROXY。如果根本不想使用Go代理,则需要将其设置为off。



引入了一个新的环境变量GOPRIVATE,是一个逗号分隔的支持glob匹配规则的列表。这可用于绕过GOPROXY某些路径的代理,尤其是公司中的私有库(例如:)GOPRIVATE=*.internal.company.com。



(白话翻译:GOPROXY设置例如GOPROXY=https://goproxy.cn,direct,意思是,首先尝试从https://goproxy.cn进行下载,如果没有,启用direct,即从仓库的的源地址下载,比如 githu.com/spf13/viper 这个路径,会使用https://githu.com/spf13/viper 这个路径进行下载。GOPRIVATE变量相当于同时设置了GONOPROXY和GONOSUMDB,即对某个指定的私有仓库,直接从私有仓库拉取而不走github,而且不对模块进行校验)



所有这些更改表明Go模块代理是Go模块的核心和重要部分。



https://segmentfault.com/a/1190000020293616



问:在 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。



https://segmentfault.com/a/1190000020293616



https://juejin.im/post/5d8ee2db6fb9a04e0b0d9c8b



https://goproxy.io/zh/



go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct



设置不走 proxy 的私有仓库,多个用逗号相隔(可选)


go env -w GOPRIVATE=*.corp.example.com



设置不走 proxy 的私有组织(可选)


go env -w GOPRIVATE=example.com/org_name



https://github.com/goproxyio/goproxy



三、GoLand设置
路径:GoLand —> Perferences —> Go —> Go Modules(vgo)—> Proxy;
设置上面给出的地址;
重启即可使用;



https://blog.csdn.net/tmt123421/article/details/88665248



Category golang