百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

为什么要使用 Go module proxy

toyiye 2024-06-21 12:00 16 浏览 0 评论

在看过 Go module 的简介之后,我以为我已经知道了这个功能我需要知道的一切。但是很快,我意识到并不是这样。最近,人们开始提倡使用 Go module proxy。在研究了利弊之后,我得出结论,这将是近年来 Go 语言 最重要 的变化之一。但为什么会这样呢?是什么让 Go module 代理如此特别?

使用 Go modules 时,如果向干净的缓存的计算机上添加新依赖项或构建 Go module,它将基于 go.mod 将下载(go get)所有依赖项,并将其缓存以供进一步操作。你也可以使用 -mod=vendor 参数构建 vendor 文件夹,来绕过缓存,以及后边使用这些下载的依赖。

但以上两种方法都不完美,我们应该可以做得更好。

(不)使用 vendor 文件夹的问题

使用 vendor 文件夹的问题

  • 在模块感知模式[1]开启时,使用 go 命令,默认不再使用 vendor 文件夹。如果你不附加 -mod=vendor 参数,这个文件夹将不会被启用。这通常引发问题,并导致必须使用其他陈旧的方案来支持老 Go 版本程序(请参考:在 Travis CI 上使用 Go Module 和 vendor[2]
  • vendor 文件夹,会占用大量磁盘空间,特别是在比较大的单体应用中。这也将增加代码仓库的克隆时间。可能你认为只用克隆一次,实际却不是这样。CI/CD 在每次事件(比如:pull request )都会触发克隆代码。因此,这将长期导致更长的编译时间,并将影响团队中的每个人。
  • 使用新的依赖通常会导致难以审核代码的变化。大多数情况下,你必须将依赖项与实际的业务逻辑捆绑在一起,这导致难以进行更改。

不使用的 vendor 的问题

  • go 程序将去源码仓库下载这些依赖。总是存在任何依赖可能在将来消失的风险(记住左边的传奇故事[3])。
  • 版本管理系统(例如 github.com )可能关闭。在这种情况下,你将无法再次构建项目。
  • 有些公司不希望内网接入外网,此时,没有 vendor 文件夹,我们将无法使用。
  • 假设发布的依赖 tag 是 v1.3.0 ,并且已经 go get 获取它到本地缓存。此时,依赖的所有者可以通过推送具有相同 tag 的恶意内容来破坏代码库。如果在具有干净缓存的计算机上重建 Go module,它现在将使用被破坏的包。为了防止这种情况,需要将 go.sum 和 go.mod 文件放在一起 。
  • 一些依赖使用不只使用 git 作为 版本管理系统,还有可能使用 hg(Mercurial),bzr(Bazaar) 或 svn(Subversion)。而你的机器没有安装装或者 Dockerfile 没有配置这些工具,这都将引发问题。
  • go get 需要获取 go.mod 列出的每个依赖项的源代码来解决递归依赖(需相应的 go.mod 文件)。因为它意味着必须下载(例如 git clone )每个存储库以获取单个文件[4],这显然会使得整个构建过程变慢。

那我们怎么解决这些问题呢?

使用 Go module proxy 的好处

默认情况下, go 命令会直接从版本管理系统下载代码。GOPROXY 环境变量允许在下载源的进一步控制。配置该环境变量后,go 命令可以使用 Go module proxy。

设置环境变量 GOPROXY 开启 Go module proxy 后,将解决上边提到的所有问题。

  • Go module proxy 默认永久缓存所有依赖(不可变存储)。这意味着,不必再使用 vendor 文件夹。
  • 抛弃 vendor 文件夹,它将不会再消耗代码库的空间。
  • 因为依赖项存储在 不可变存储 中,即使依赖项从网上消失,你的代码也会受到保护。
  • 一旦 Go module(依赖) 存储在 Go proxy 中,就无法覆盖或删除它。这可以保护你免受可能使用相同版本注入恶意代码的攻击。
  • 你不再需要任何 VSC 工具来下载依赖项,因为依赖项是通过 HTTP 获取的( Go proxy 在后台使用 HTTP)。
  • 下载和构建 Go module 的速度要快得多,因为 Go proxy 通过 HTTP 独立提供源代码(.zip 存档)go.mod。与从 VCS 获取相比,由于更少的开销,这使得下载花费更少的时间。相比之前它必须获取整个存储库,解决依赖关系也更快,因为 go.mod 可以独立获取。Go 官方团队对它进行了测试,他们看到快速网络上的速度提高了 3 倍,而慢速网络则提高了 6 倍!
  • 你可以轻松运行自己的 Go proxy ,这可以让你更好地控制构建管道的稳定性,并防止 VCS 关闭时的罕见情况。

如你所见,使用 Go module proxy 对人人都有好处。但是我们如何使用它呢?如果你不想维护自己的 Go module proxy 怎么办?这里还有许多替代方案。

如何使用 Go module proxy

要开始使用 Go module proxy,我们需要将 GOPROXY 环境变量设置为兼容的 Go module proxy。这有多种方式:

  1. 如果没有设置 GOPROXY,将其设置为空或设置为 direct ,然后 go get 将直接到 VCS(例如 github.com)拉取代码:
GOPROXY=""
GOPROXY=direct
  1. GOPROXY 也可以设置为 off,这意味着不允许使用网络
GOPROXY=off
  1. 你可以开始使用公共 GOPROXY 。你也可以选择使用 Go 官方团队的 GOPROXY(由 Google 运营)。更多信息可以在这里找到:https://proxy.golang.org/
  2. 要开始使用它,你只需设置环境变量:
GOPROXY=https://proxy.golang.org
  1. 其他可用的公共代理:
GOPROXY=https://goproxy.io
GOPROXY=https://goproxy.cn # proxy.golang.org 被墙了, 这个没有
  1. 你可以运行多个开源实现并自己托管。可用的有:
  2. 你既可以自己维护,也可以通过公共互联网或内部网络获取相关服务,看你自己的决定。
  3. Athens:https://github.com/gomods/athens
  4. goproxy:https://github.com/goproxy/goproxy
  5. THUMBAI:https://thumbai.app/
  6. 你可以购买商业产品:
  7. Artifactory: https://jfrog.com/artifactory/
  8. 你可以传入 file:/// 路由。因为 Go module proxy 是响应 GET 请求(没有查询参数)的 Web 服务器,所以任何文件系统中的文件夹都可以用作 Go module proxy。

Go 1.13 的变化

在 Go v1.13 版本中, Go proxy 有一些变化,我认为应该强调一下:

  1. 在 GOPROXY 环境变量现在可以设置为逗号分隔的列表。它会在回到下一个路径之前尝试第一个代理。
  2. GOPROXY 的默认值为 https://proxy.golang.org,direct。设置 direct 后将忽略之后的所有内容。这也意味着 go get 现在将默认使用 GOPROXY 。如果你根本不想使用 GOPROXY,则需要将其设置为 off。
  3. 新版本引入了一个新的环境变量 GOPRIVATE ,它包含以逗号分隔的 全局列表。这可用于绕过 GOPROXY 某些路径的代理,尤其是公司中的私有模块(例如: GOPRIVATE=*.internal.company.com)。

所有这些变化都表明 Go module proxy 将是 Go module 的核心和重要组成。

总结

无论使用公共网络,还是专用网络, GOPROXY 都有很多优势。这是一个很棒的工具,它可以和 go 命令无缝协作。鉴于它具有如此多的优势(安全,快速,存储高效),明智的做法是在您的项目或组织中快速接受它。此外,在 Go v1.13 版本中,默认情况下 GO111MODULE 为 auto 了,这是另一个受欢迎的步骤,它改善了 Go 中依赖项管理的现状,将来会默认启用 Module。


via: https://arslan.io/2019/08/02/why-you-should-use-a-go-module-proxy/

作者:Fatih Arslan[5]译者:TomatoAres[6]校对:polaris1119[7]

本文由 GCTT[8] 原创编译,Go 中文网[9] 荣誉推出


喜欢本文的朋友,欢迎关注“Go语言中文网”:

文中链接

[1]模块感知模式: https://golang.org/cmd/go/#hdr-Modules_and_vendoring

[2]在 Travis CI 上使用 Go Module 和 vendor: https://arslan.io/2018/08/26/using-go-modules-with-vendor-support-on-travis-ci/

[3]记住左边的传奇故事: https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code/

[4]获取单个文件: https://about.sourcegraph.com/go/gophercon-2019-go-module-proxy-life-of-a-query

[5]Fatih Arslan: https://arslan.io/

[6]TomatoAres: https://github.com/TomatoAres

[7]polaris1119: https://github.com/polaris1119

[8]GCTT: https://github.com/studygolang/GCTT

[9]Go 中文网: https://studygolang.com/

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码