半瘦金山 發表於 2019-11-23 13:51:00

Go Modules与GOPROXY 配置

<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
                        <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0)"></path>
                  </svg>
                                          <p>golangd 配置go mod 在博文底部</p>
<p>摘抄自https://studygolang.com/articles/24544go语言中文网在原基础博客整理增加知识点   让你彻底名表go mod<br>
随着Go 1.13发布,GOPROXY默认值proxy.golang.org在中国大陆不能被访问。</p>
<p>七牛云顺势推出goproxy.cn,以利于中国开发者更好使用Go Modules,它是非盈利性的项目,首先感谢七牛云。</p>
<p>Windows下使用教程:</p>
<p>(1)升级到Go1.13</p>
<p>(2)运行&lt;go env -w GO111MODULE=on&gt;                                 //开启mod</p>
<p>(3)运行&lt;go env -w GOPROXY=https://goproxy.cn,direct&gt;   //设置七牛云goproxy代理</p>
<p>可以通过运行go env查看(2)、(3)步骤是否设置成功</p>
<p><img src="https://img-blog.csdnimg.cn/2019112313484469.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpdXF1bjAzMTk=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>
(4)在项目跟目录下执行go mod init &lt;OPTIONAL_MODULE_PATH&gt;</p>
<p>执行成功后生成go.mod文件</p>
<p>其他指令</p>
<blockquote>
<p>go get -u //更新现有的依赖<br>
go mod tidy //整理模块(拉取缺少的模块,移除不用的模块)<br>
go mod download//下载依赖包<br>
go mod graph //打印现有依赖结构<br>
go mod vendor //将依赖复制到vendor下<br>
go mod verify //校验依赖<br>
go.mod文件解析<br>
module:模块名称,使用指令go mod init &lt;OPTIONAL_MODULE_PATH&gt;可设置<br>
require:依赖包列表以及版本<br>
exclude:禁用依赖包列表<br>
replace:替换依赖包列表<br>
go:go版本号</p>
</blockquote>
<p>goland编辑器中配置go mod</p>
<blockquote>
<p>在goland的setting里设置启用Go Modules<br>
goland Preference-&gt;Go-&gt;Go Modules(vgo) -&gt; Enable Go Modules(vgo)intergration</p>
</blockquote>
<p><img src="https://img-blog.csdnimg.cn/20191224113345827.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpdXF1bjAzMTk=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<blockquote>
<p>勾选 Enable Go Modules(vgo)intergration之后,</p>
</blockquote>
<blockquote>
<p>proxy配置(参考上图)<br>
https://goproxy.cn<br>
点击apply (应用)ok 即可。</p>
</blockquote>
<p><font color="red"><strong>______________________________________________________________</strong></font><br>
<font color="red"><strong>______________________________________________________________</strong></font></p>
<hr>
<p>gomod 的相关知识摘抄自go 夜读 (author:盛傲飞)<br>
<img src="https://img-blog.csdnimg.cn/20191225155456732.png" alt="在这里插入图片描述"><br>
go.mod</p>
<pre><code class="prism language-go">module sss

<span class="token keyword">go</span> <span class="token number">1.13</span>

require <span class="token punctuation">(</span>
        github<span class="token punctuation">.</span>com<span class="token operator">/</span>astaxie<span class="token operator">/</span>beego v1<span class="token punctuation">.</span><span class="token number">12.0</span>
        github<span class="token punctuation">.</span>com<span class="token operator">/</span><span class="token keyword">go</span><span class="token operator">-</span>sql<span class="token operator">-</span>driver<span class="token operator">/</span>mysql v1<span class="token punctuation">.</span><span class="token number">4.1</span>
        github<span class="token punctuation">.</span>com<span class="token operator">/</span>julienschmidt<span class="token operator">/</span>httprouter v1<span class="token punctuation">.</span><span class="token number">3.0</span>
        github<span class="token punctuation">.</span>com<span class="token operator">/</span>micro<span class="token operator">/</span>examples v0<span class="token punctuation">.</span><span class="token number">2.0</span>
        github<span class="token punctuation">.</span>com<span class="token operator">/</span>micro<span class="token operator">/</span><span class="token keyword">go</span><span class="token operator">-</span>micro v1<span class="token punctuation">.</span><span class="token number">18.0</span>
<span class="token punctuation">)</span>
</code></pre>
<p>go.mod 是启用了 Go moduels 的项目所必须的最重要的文件,它描述了当前项目(也就是当前模块)的元信息,每一行都以一个动词开头,目前有以下 5 个动词:</p>
<ul>
<li>module:用于定义当前项目的模块路径。</li>
<li>go:用于设置预期的 Go 版本。</li>
<li>require:用于设置一个特定的模块版本。</li>
<li>exclude:用于从使用中排除一个特定的模块版本。</li>
<li>replace:用于将一个模块版本替换为另外一个模块版本。</li>
</ul>
<p>这里的填写格式基本为包引用路径+版本号,另外比较特殊的是 go $version,目前从 Go1.13 的代码里来看,还只是个标识作用,暂时未知未来是否有更大的作用。<br>
go.sum<br>
go.sum 是类似于比如 dep 的 Gopkg.lock 的一类文件,它详细罗列了当前项目直接或间接依赖的所有模块版本,并写明了那些模块版本的 SHA-256 哈希值以备 Go 在今后的操作中保证项目所依赖的那些模块版本不会被篡改。</p>
<pre><code class="prism language-go">example<span class="token punctuation">.</span>com<span class="token operator">/</span>apple v0<span class="token punctuation">.</span><span class="token number">1.2</span> h1<span class="token punctuation">:</span>WX<span class="token operator">...</span>
example<span class="token punctuation">.</span>com<span class="token operator">/</span>apple v0<span class="token punctuation">.</span><span class="token number">1.2</span><span class="token operator">/</span><span class="token keyword">go</span><span class="token punctuation">.</span>mod h1<span class="token punctuation">:</span>xHW<span class="token operator">...</span>
example<span class="token punctuation">.</span>com<span class="token operator">/</span>banana v1<span class="token punctuation">.</span><span class="token number">2.3</span><span class="token operator">/</span><span class="token keyword">go</span><span class="token punctuation">.</span>mod h1<span class="token punctuation">:</span>HS<span class="token operator">...</span>
<span class="token operator">...</span>
</code></pre>
<pre><code class="prism language-go">example<span class="token punctuation">.</span>com<span class="token operator">/</span>apple v0<span class="token punctuation">.</span><span class="token number">1.2</span> h1<span class="token punctuation">:</span>WXk<span class="token operator">...</span>
example<span class="token punctuation">.</span>com<span class="token operator">/</span>apple v0<span class="token punctuation">.</span><span class="token number">1.2</span><span class="token operator">/</span><span class="token keyword">go</span><span class="token punctuation">.</span>mod h1<span class="token punctuation">:</span>xH<span class="token operator">...</span>
</code></pre>
<p>前者为 Go modules 打包整个模块包文件 zip 后再进行 hash 值,而后者为针对 go.mod 的 hash 值。他们两者,要不就是同时存在,要不就是只存在 go.mod hash。</p>
<p>那什么情况下会不存在 zip hash 呢,就是当 Go 认为肯定用不到某个模块版本的时候就会省略它的 zip hash,就会出现不存在 zip hash,只存在 go.mod hash 的情况。</p>
<p>GO111MODULE<br>
这个环境变量主要是 Go modules 的开关,主要有以下参数:</p>
<ul>
<li>auto:只在项目包含了 go.mod 文件时启用 Go modules,在 Go 1.13 中仍然是默认值,详见 :golang.org/issue/31857。</li>
<li>on:无脑启用 Go modules,推荐设置,未来版本中的默认值,让 GOPATH 从此成为历史。</li>
<li>off:禁用 Go modules。</li>
</ul>
<p>GOPROXY<br>
这个环境变量主要是用于设置 Go 模块代理,主要如下:</p>
<ul>
<li>它的值是一个以英文逗号 “,” 分割的 Go module proxy 列表(稍后讲解)</li>
<li>作用:用于使 Go 在后续拉取模块版本时能够脱离传统的 VCS 方式从镜像站点快速拉取。它拥有一个默认值,但很可惜 proxy.golang.org 在中国无法访问,故而建议使用 goproxy.cn 作为替代。</li>
<li>设置为 “off” :禁止 Go 在后续操作中使用任 何 Go module proxy。</li>
</ul>
<p>刚刚在上面,我们可以发现值列表中有 “direct” ,它又有什么作用呢?<br>
其实值列表中的 “direct” 为特殊指示符,用于指示 Go 回源到模块版本的源地址去抓取 (比如 GitHub 等),当值列表中上一个 Go module proxy 返回 404 或 410 错误时,Go 自动尝试列表中的下一个,遇见 “direct” 时回源,遇见 EOF 时终止并抛出类似 “invalid version: unknown revision…” 的错误。</p>
<p>GOSUMDB<br>
它的值是一个 Go checksum database,用于使 Go 在拉取模块版本时(无论是从源站拉取还是通过 Go module proxy 拉取)保证拉取到的模块版本数据未经篡改,也可以是“off”即禁止 Go 在后续操作中校验模块版本</p>
<ul>
<li>格式: SUMDB_NAME+PUBLIC_KEY或SUMDB_NAME+PUBLIC_KEY SUMDB_URL。</li>
<li>拥有默认值: sum.golang.org (之所以没有按照上面的格式是因为 Go 对默认值做了特殊处理)。</li>
<li>可被 Go module proxy 代理 (详见:Proxying a Checksum Database)。</li>
<li>GOSUMDB 的默认值在中国无法访问,故而更加建议将 GOPROXY 设置为 goproxy.cn,因为 goproxy.cn 支持代理 sum.golang.org。</li>
</ul>
<p>Go Checksum Database<br>
Go checksum database 主要用于保护 Go 不会从任何源头拉到被篡改过的非法 Go 模块版本,其作用(左)和工作机制(右)如下图:<br>
<img src="https://img-blog.csdnimg.cn/20191225161647426.png" alt="在这里插入图片描述"><br>
如果有兴趣的小伙伴可以看看 Proposal: Secure the Public Go Module Ecosystem,有详细介绍其算法机制,如果想简单一点,查看 go helpmodule-auth 也是一个不错的选择。</p>
<p>GONOPROXY/GONOSUMDB/GOPRIVATE<br>
这三个环境变量都是用在当前项目依赖了私有模块,也就是依赖了由 GOPROXY 指定的 Go module proxy 或由 GOSUMDB 指定 Go checksum database 无法访问到的模块时的场景,他们具有如下特性:</p>
<ul>
<li>
<p>它们三个的值都是一个以英文逗号 “,” 分割的模块路径前缀,匹配规则同 path.Match。</p>
</li>
<li>
<p>其中 GOPRIVATE 较为特殊,它的值将作为 GONOPROXY 和 GONOSUMDB 的默认值,所以建议的最佳姿势是只是用 GOPRIVATE。</p>
</li>
</ul>
<p>在使用上来讲,比如 GOPRIVATE=*.corp.example.com 表示所有模块路径以 corp.example.com 的下一级域名 (如 team1.corp.example.com) 为前缀的模块版本都将不经过 Go module proxy 和 Go checksum database,需要注意的是不包括 corp.example.com 本身。<br>
Global Caching<br>
这个主要是针对 Go modules 的全局缓存数据说明,如下:</p>
<ul>
<li>同一个模块版本的数据只缓存一份,所有其他模块共享使用。</li>
<li>目前所有模块版本数据均缓存在 $GOPATH/pkg/mod和$GOPATH/pkg/sum 下,未来或将移至 $GOCACHE/mod和 $GOCACHE/sum 下( 可能会在当 $GOPATH 被淘汰后)。</li>
<li>可以使用 go clean-modcache 清理所有已缓存的模块版本数据。</li>
</ul>
<p>另外在 Go1.11 之后 GOCACHE 已经不允许设置为 off 了,我想着这也是为了模块数据缓存移动位置做准备,因此大家应该尽快做好适配。</p>
<p>++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=</p>
<h2>快速迁移项目至 Go Modules</h2>
<p><img src="https://img-blog.csdnimg.cn/20191225162242621.png" alt="在这里插入图片描述"></p>
<ul>
<li>
<p>升级到 Go 1.13。</p>
</li>
<li>
<p>让 GOPATH 从你的脑海中完全消失,早一步踏入未来。</p>
<ul>
<li>修改 GOBIN 路径(可选)。</li>
<li>打开 Go modules 的开关。</li>
<li>设置 GOPROXY。</li>
</ul>
</li>
<li>
<p>按照你喜欢的目录结构重新组织你的所有项目。</p>
</li>
<li>
<p>在你项目的根目录下执行 go mod init&lt;OPTIONAL_MODULE_PATH&gt; 以生成 go.mod 文件。</p>
</li>
<li>
<p>想办法说服你身边所有的人都去走一下前四步。</p>
</li>
</ul>
<h2>迁移后 go get 行为的改变</h2>
<p>这里我们注意到有两点比较特别,分别是:<br>
<img src="https://img-blog.csdnimg.cn/20191225162805734.png" alt="在这里插入图片描述"></p>
<ul>
<li>第一点:为什么 “拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2” 呢。这是因为虽然我们设置了拉取 @342b2e commit,但是因为 Go modules 会与 tag 进行对比,若发现对应的 commit 与 tag 有关联,则进行转换。</li>
<li>第二点:为什么不建议使用 go mod vendor,因为 Go modules 正在淡化 Vendor 的概念,很有可能 Go2 就去掉了。</li>
</ul>
<h2>使用 Go Modules 时常遇见的坑</h2>
<h3>坑 1: 判断项目是否启用了 Go Modules</h3>
<p><img src="https://img-blog.csdnimg.cn/20191225162938359.png" alt="在这里插入图片描述"></p>
<h3>坑 2: 管理 Go 的环境变量</h3>
<p><img src="https://img-blog.csdnimg.cn/20191225163003224.png" alt="在这里插入图片描述"><br>
这里主要是提到 Go1.13 新增了 go env-w 用于写入环境变量,而写入的地方是 os.UserConfigDir 所返回的路径,需要注意的是 go env-w 不会覆写。</p>
<h3>坑 3: 从 dep、glide 等迁移至 Go Modules</h3>
<p><img src="https://img-blog.csdnimg.cn/20191225163103603.png" alt="在这里插入图片描述"><br>
这里主要是指从旧有的依赖包管理工具(dep/glide 等)进行迁移时,因为 BUG 的原因会导致不经过 GOPROXY 的代理,解决方法有如下两个:</p>
<ul>
<li>手动创建一个 go.mod 文件,再执行 go mod tidy 进行补充。</li>
<li>上代理,相当于不使用 GOPROXY 了。</li>
</ul>
<h3>坑 4:拉取私有模块</h3>
<p><img src="https://img-blog.csdnimg.cn/2019122516325826.png" alt="在这里插入图片描述"><br>
这里主要想涉及两块知识点,如下:</p>
<ul>
<li>GOPROXY 是无权访问到任何人的私有模块的,所以你放心,安全性没问题。</li>
<li>GOPROXY 除了设置模块代理的地址以外,还需要增加 “direct” 特殊标识才可以成功拉取私有库。</li>
</ul>
<h3>坑 5:更新现有的模块</h3>
<p><img src="https://img-blog.csdnimg.cn/20191225163309300.png" alt="在这里插入图片描述"></p>
<h3>坑 6:主版本号</h3>
<p><img src="https://img-blog.csdnimg.cn/20191225163320936.png" alt="在这里插入图片描述"></p>
<p>Q:使用 Go modules 时可以同时依赖同一个模块的不同的两个或者多个小版本(修订版本号不同)吗?</p>
<p>A:不可以的,Go modules 只可以同时依赖一个模块的不同的两个或者多个大版本(主版本号不同)。比如可以同时依赖 example.com/foobar@v1.2.3 和 example.com/foobar/v2@v2.3.4,因为他们的模块路径(module path)不同,Go modules 规定主版本号不是 v0 或者 v1 时,那么主版本号必须显式地出现在模块路径的尾部。但是,同时依赖两个或者多个小版本是不支持的。比如如果模块 A 同时直接依赖了模块 B 和模块 C,且模块 A 直接依赖的是模块 C 的 v1.0.0 版本,然后模块 B 直接依赖的是模块 C 的 v1.0.1 版本,那么最终 Go modules 会为模块 A 选用模块 C 的 v1.0.1 版本而不是模块 A 的 go.mod 文件中指明的 v1.0.0 版本。</p>
<p>这是因为 Go modules 认为只要主版本号不变,那么剩下的都可以直接升级采用最新的。但是如果采用了最新的结果导致项目 Break 掉了,那么 Go modules 就会 Fallback 到上一个老的版本,比如在前面的例子中就会 Fallback 到 v1.0.0 版本。</p><br><br>
来源:https://www.cnblogs.com/liuqun/p/12655150.html
頁: [1]
查看完整版本: Go Modules与GOPROXY 配置