前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10分钟将你的Go工程转换为Go Module模式

10分钟将你的Go工程转换为Go Module模式

原创
作者头像
JFrog杰蛙科技
修改2019-12-20 10:38:46
1.3K0
修改2019-12-20 10:38:46
举报
文章被收录于专栏:JFrog杰蛙DevOpsJFrog杰蛙DevOps

自从在Go 1.11和高版本中引入了Go的新管理系统以来,GoLang开发人员已经接受了包版本控制解决方案。这样做的用户可以使用GoCenter存储库中的不可变公共Go 模块,并通过健壮、可靠的Go Pipeline获得快的构建速度。

但是,将现有的项目转换为使用Go Module并不总是很容易,如果该项目已经尝试过GoLang的其他包管理解决方案时。

为了帮助GoLang社区正确地使用Go Module,我们将使用开源的etcd项目(Kubernetes使用的键值数据存储)作为示例。这是一个实践的实际示例,因为它很复杂,可以展示一些常见的实践

Go 项目依赖管理痛点分析

传统GO项目进行第三方模块依赖时,往往是去下载第三方源码,这种方式将存在以下常见问题:

1. 性能及稳定性:每次下载从各大VCS系统下载源码性能低,依赖网络环境,稳定性差

2. 一致性&可重复性:容易收到依赖源的影响,我们往往在感知不到模块提供方的改动时,就下载了新版的代码,两次依赖某模块得到的依赖不一致,往往造成前一秒还行,下一秒构建失败的情形,尤其在持续集成系统中

3. 协作:源码方式模块基本无版本概念,或不是语义类型,多团队协作困难

基于以上问题及痛点,建议转换为Go Module 模式管理Go 项目依赖。附Go Module 基于Go Proxy进行依赖下载的原理图:

应用Go Module方式后可以获得以下收益:

  1. 可用性(标签tag可以从VCS中删除)
  2. 不变性(可以在VCS中进行更改)
  3. 快速:(没有git,没有计算元数据,调用更少,性能好)
  4. 本地统一存储缓存($GOPATH/pkg /mod/cache)

Go模块转换实践

我们以ETCD项目为例进行转换,这个转换过程已通过测试用例的验证,可以到该项目中的Pull Request中查看

步骤一:准备go.mod文件

对于以前从未使用过模块的项目(没有go.mod 文件),或者任何现在不推荐的依赖项管理解决方案,这个过程都非常简单。您只需要在项目的根目录中运行go mod tidy。这将生成一个新的、已填充好该项目依赖描述的go.mod文件。

但是,如果项目使用了那些较老的解决方案之一,比如dep、glide、govendor或godep,那么您将需要运行go mod init来生成填充的go.mod文件。该命令支持旧格式中依赖项描述。

etcd项目确实有一个go.mod文件,尽管它从未在项目的构建系统中启用。问题是模块名称没有正确的版本标识符,因为当前版本标记是v2+。由于语义化导入版本控制的影响,需要更改为v3。

其包括执行以下过程:

1. 更新etcd的go.mod文件以修正模块名称,使其包含v3后缀。

2. 更新所有代码中的Import以包含版本号。我们编写了一个脚本,以便更容易地修改所有引用。完成后,此更改如下:

步骤二 : 启用Go模块

要使go客户端能够使用go module,需要设置GO111MODULE=on

正如我们所指出的,etcd项目已经设置了go.mod文件,有人可能认为这已经完成了。但它没有,而该环境变量这种缺失证实了该项目还没有使用go module。

注意:从Go 1.13开始,这一步将不再需要,因为Go Module将在默认情况下启用

步骤三 : 更新测试中的导入

在上面的过程中,我们对组成etcd主模块的go.mod文件进行了更新,以使用v3版本标记。现在主模块被标记为v3,我们还需要更新etcd项目的测试用例中的Import引用v3,以确保它们导入了主模块的正确版本。

步骤四 : 其他更新

在这些更改之后,您可能希望保持良好的状态—毕竟,应用程序模块现在已经全部转换为使用go module,并使用正确的版本标记。

不过没那么快。一旦你开始运行测试,你会发现两个额外的场景需要处理:

1. etcd使用了诸如golint、gosimple、staticcheck、ineffassign等静态分析工具,但其中一些工具没有模块意识,无法识别模块路径,而无法通过必要的检查。在etcd的这种场景下,etcd-io/etcd下并没有v3文件夹,但是Import导入(或模块路径)包含v3,如etcd-io/etcd/v3。其他工具是模块感知的,但必须在新版本的Go 1.12中可用。如果构建系统在1.11之上,那么它们也需要迁移到1.12。

2. 如果使用了protobuf之类的代码生成器。更新.proto文件,以便使用正确版本的导入生成代码。

步骤五 : 加入GoCenter

在构建过程中,您可能会注意到许多go get命令在etcd的不同阶段执行。

为了加快GoLang应用程序的构建时间,并确保etcd ppipeline中使用的Go Module版本的不可变性和可用性,使用GoCenter来构建etcd

只需设置GOPROXY=https://gocenter.io。(详细原理可看上文的Go Proxy 原理图)

总结

正如您所看到的,将Go项目转换为使用Go Module方式非常简单,但是有一些细节可能会减慢您的速度。通过选择这个具有丰富场景的项目来演示这个过程,我们相信我们达到了大多数需要处理的场景,为您提供了一个很好的示例,覆盖了您可能面临的情况。

大家感兴趣可以测试一下旧的依赖管理方式和Go Module方式的性能对比,请参考:

https://jfrog.com/blog/build-times-matter-speed-is-everything/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Go 项目依赖管理痛点分析
  • Go模块转换实践
    • 步骤一:准备go.mod文件
      • 步骤二 : 启用Go模块
        • 步骤三 : 更新测试中的导入
          • 步骤四 : 其他更新
            • 步骤五 : 加入GoCenter
            • 总结
            相关产品与服务
            持续集成
            CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档