GoCenter助力Golang全速前进

一、背景

Go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。为了方便搜索和识别,有时会将其称为Golang。自2009年11月Google正式宣布推出,成为开放源代码项目以来,Go语言已成为当今开发人员和DevOps领域最流行的语言之一, 它被用于设计和编写Kubernetes和Helm。但是,相比语言本身已经得到了广泛的普及和使用,Go语言的包管理方案却大大滞后了。

Go语言生态系统中缺少的是标准化——没有用于依赖关系管理的标准工具, 也没有标准的包格式或兼容的包仓库规范。这意味着开发人员无法使用Go语言创建可重现的构建, 这是一个相当大的问题。这些年来, 社区推出了诸如dep、godep、glide和govender等工具,试图用来处理Go语言的依赖管理, 但并未成功。2018年Google在Go1.11官方推出了Go modules,为Go语言提供了支持版本化的依赖管理方案。

Go modules现在已成为Go语言标准的依赖管理工具和包仓库规范。而GoCenter为Go modules的实现和推广提供了依赖包的公共仓库,使得Go语言的开发人员能够更为稳定和方便地开发可重复构建的Go应用程序。


二、Go语言的依赖管理

在介绍GoCenter之前,我们先简要地回顾一下Go语言依赖管理的发展历程。

Go语言在推出之初,并没有明确的依赖管理方案。只是在构建过程中通过go get命令,将用import声明的依赖从对应的源,通常是git上的项目,下载到$GOPATH/src目录下,和Go应用自身的代码放在一起。这种依靠GOPATH来管理依赖的机制带来的问题是显而易见的,比如:

·因源依赖包自身的变化,导致不同时间构建Go应用时go get得到的依赖实质上是不同的,即不能实现可重复的构建;

·或者因源依赖包自身的变化,重新构建Go应用时会引入不兼容的新实现,导致Go应用无法通过编译。

因此在1.5版本以前,为了规避这个问题,通常需要将使用的依赖包手工拷贝出来。

为了实现Go应用的可重复构建,Go1.5引入了Vendor机制。Vendor机制的核心就是在GOPATH下面增加了vendor文件夹。Go应用所需的依赖都可以从依赖源fork出所需的分支,存放到vendor文件夹。当构建Go应用时,Go编译器会优先在vendor文件夹下搜索依赖的第三方包,vendor文件夹下没有才会再到$GOPATH/src下去找。这样只要开发者预先将特定版本的依赖包存放在vendor文件夹,并提交到Go 项目的code repo,那么所有人理论上都会得到同样的编译结果,从而实现可重复构建。在Go1.5发布后的若干年,Go社区把注意力都集中在如何利用Vendor机制解决Go应用的依赖管理问题,并诞生了众多的依赖管理工具,如dep、golide、govendor等。然而,和Java的Maven、Python的Pypi、C/C++的Conan等业界成熟的依赖管理方案相比,Vender机制仍然存在许多问题,比如:

·Vendor文件夹中的依赖包没有版本信息。这样依赖包脱离了版本管理,对于一致性管理、升级,以及问题追溯等场景,都会难以处理;

·Vendor机制没有给出如何能够方便地得到Go项目依赖了哪些包,并将其拷贝到vendor文件夹下的方案,多数情况下还需要到不同的Git源项目里手工拷贝;

·当依赖的包比较多的时候,vendor文件夹也会变得非常庞大。

2018年年初,Go核心Team的技术leader,也是Go

Team最早期成员之一的Russ Cox个人博客上连续发表了七篇文章,系统阐述了Go team解决“包依赖管理”的技术方案:vgo。vgo的主要思路包括:语义导入版本控制(Semantic Import

Versioning)、最小版本选择(Minimal Version Selection)、以及引入Go module等。同年5月份,Russ Cox的提案“cmd/go: add package version support

to Go toolchain”被社区接受,vgo的代码合并到Go主干,并将这套机制正式命名为“go modules”。由于vgo项目本身就是一个实验原型,merge到主干后,vgo这个术语以及vgo项目的使命也就此结束了。后续Go modules机制将直接在Go主干上继续演化。

Go modules机制的主要变化包括:

· 去除了饱受诟病的GOPATH的限制。Go编译器将不再到GOPATH下面的vendor或src文件夹下搜索Go应用构建依赖的第三方包;

· Go modules机制为在同一应用repo下面的包赋予了一个新的抽象概念: 模块(module),即可重用的Go代码包,并启用一个新的文件go.mod记录模块的元信息和依赖关系。而在go.mod里明确描述了依赖包的版本信息,同一个依赖包也可以记录多个不同的版本。除了精确版本外,go.mod还支持用表达式模糊地定义依赖版本;

· 在Go modules机制下,还支持创建Go依赖包的公共仓库。这是因为应用程序包含的Go模块,必须从数千个独立的源代码存储库中解析,而每个存储库的维护纪律可能各不相同。因此,需要存在一个可公开访问的存储库,通过Go modules提供的依赖描述、解析机制,为Go的开发者提供一致的、可分享的、支持重复构建的、稳定的Go依赖包源。GoCenter就是这种Go依赖包公共仓库的重要实现。


三、GoCenter简介

GoCenter通过创建Go模块的公共中央仓库,提供可重复和快速依赖解析的依赖包管理方案,解决了Go开发人员查找和获取Go依赖包的困难。GoCenter将直接从源代码存储库获取Go项目,转变为处理和验证不可变的、具备版本控制的Go模块, 并将其免费提供给Go应用的开发人员。

GoCenter(https://gocenter.io)提供了通过公共Go代理解析模块, 包括通过托管免费服务搜索模块的能力。从创建开始, GoCenter已经包括了数千个广受欢迎的Go项目的模块, Go开发者可以立即使用这些项目进行自己的构建。

开发人员也可以提交自己的Go项目加入GoCenter,以便将其提供给Go社区开发者,从而得到更为广泛地应用。

GoCenter这个中央仓库,提供了预先打包,以及版本化的Go模块,使得Go开发人员或团队不再需要为使用公共模块而构建自己的模块库,从而消减了使用Go 语言的巨大成本。

此外,如果Go开发者或团队已经有了自己的JFrog Artifactory仓库,就可以通过配置指向GoCenter的远程仓库,为重复构建提供完全的本地化控制,并可以预防访问GoCenter的网络连接问题。


四、基于GoCenter构建Go应用

要构建Go应用项目,首先需要安装Go客户端(版本1.11.0 或更新的版本) 。而安装Go之后,有三种方法可以从GoCenter解析Go模块:使用goc、使用 go 客户端,或部署本地仓库(如Artifactory),以代理GoCenter。

1、使用goc

推荐在构建中使用GoCenter的方式是通过goc工具。goc工具包装了Go的客户端,器, 能够使用GoCenter中的包正确构建Go应用,而无需手动设置。

要安装goc,需要使用以下的curl命令,或按照goc的github主页(https://github.com/jfrog/goc)的说明:

$ curl -fLhttps://getgoc.gocenter.io | sh

然后, 就可以从Go项目的根目录中运行任何命令, 就像运行Go命令一样。例如:

$ goc build

goc工具自动分配GOPROXY连接GoCenter,所以能够优先从该仓库解析Go的依赖包。对于在GoCenter找不到的包,goc将会试图通过源代码控制系统来解析它们,以更好地保证成功构建Go项目。

Go客户端自身不能执行这种辅助操作(请参阅下文), 因此至少在 GoCenter能够为大多数Go开发人员提供可能需要的所有依赖之前,仍然建议使用goc。

2、使用Go客户端

推荐在构建中使用GoCenter的方式是通过goc工具。goc工具包装了Go的客户端,器, 能够使用GoCenter中的包正确构建Go应用,而无需手动设置。

如上所述,使用GoCenter时并不建议直接利用Go客户端进行构建,因为当在GoCenter找不到相关依赖包时构建会失败。对于Go客户端这种限制的详细信息,可以参考相关的issue和修正信息(https://github.com/golang/go/issues/26334)。Go开发人员还是应该改用goc。

当然,如果在充分了解这个限制还希望使用的情况下,也是可以使用Go客户端的。

如果希望构建Go项目时从GoCenter中获取相关依赖包,需要设置GOPROXY指向GoCenter的URL,https://gocenter.io

$ export GOPROXY=https://gocenter.io

现在就可以使用Go客户端构建Go应用了:

$ go build


3、部署代理GoCenter的私有仓库

如果使用的是如Artifactory这样的私有仓库,则只需设置GOPROXY指向该私有仓库,而把GoCenter创建为该私有仓库当中的远程仓库。

为了要在Artifactory里创建代理GoCenter的远程仓库,需要遵循以下步骤:

1. 创建新的远程仓库,并设置包类型为Go;

2. 设置远程仓库的名字,并在URL字段输入https://gocenter.io/

3. 点击“保存 & 完成”按键。

还可以创建虚拟仓库,用以聚合同时从本地Go仓库和远程仓库获取的Go依赖包。

一旦在Artifactory里配置好使用GoCenter,就可以使用标准的GOPROXY方式基于Artifactory进行构建。需要注意的是,根据Artifacotry上的设置,需要适当地处理客户端的认证信息,应为当前Go客户端在获取模块时是不会发送相关认证信息的,所以处理起来是有一定难度的。因此,当使用Artifactory代理GoCenter时,建议使用JFrog CLI来构建Go应用。当配置好JFrog CLI和Artifactory的关联之后,就可以使用类似于“ jfrog rt go build ”的命令来从Artifactory获取依赖,并构建Go应用。

使用JFrog CLI的好处是可以方便地向Artifactory上传针对特定构建而创建的依赖包,也同时内置支持生成和发布与构建过程相关的元数据。详细信息,请参考JFrog CLI的相关文档。


五、搜索Go模块

GoCenter首页中的搜索框可帮助按特定模块名称(例如, "虹膜")进行搜索。当执行搜索时,GoCenter将列出与搜索名称匹配或部分匹配的模块。

点击列表中的某个模块,将会列出GoCenter中该模块的所有版本:

列出的版本都利用颜色编码来指示其当前的可用状态:

绿色,表示该模块版本已在GoCenter之中且处于可用状态;

红色,表示该模块版本不存在,而且不可用;

灰色,表示该模块版本正在引入的过程中,尚未可用。

搜索结果还会显示那些Go项目在相关Git代码库存在,而在GoCenter尚不存在的模块版本列表。如果有这样的缺失版本,可以通过单击“Add missing version(s)”把它们 添加到GoCenter。


六、提交自己的Go模块

如果希望将自己的Go项目添加到GoCenter,使其可被Go社区的开发人员使用,则需要提交相关的加入申请。

首先可以对希望加入的模块名执行搜索。如果相关模块并不存在,则可以单击“Add”图标来请求添加模块。一旦点击,将会看到加入申请表格。在表格中,可以输入申请加入的Go模块的URL。通过搜索该模块的结果可以查看该模块的加入进度。

GoCenter将依据以下最低标准来验证加入请求:

· Go模块位于gihub.com或gopkg.in上的公共项目(repo);

· 该项目没有被设置为存档状态(archived);

· 该项目至少拥有3颗星


七、总结

自从2007年首次在谷歌构想,并于2009年正式推出,Go语言很快就成为最流行的编程语言之一。事实上,Helm和Kubernetes都是用Go语言编写的。在2017年的一项调查中,Go语言在开发者的偏好中排名最高,67%的开发者都在利用Go语言编程。

为此, 我们期望GoCenter能够为不断增长的Go社区和开发人员提供必要的服务,并帮助Go语言更加符合DevOps的需求。

通过访问GoCenter,https://gocenter.io,可以发现经常使用的Go依赖包都已经包含在其中了。如果还没有,请提交相关的加入申请。

GoCenter管理了版本化的Go模块,可以和Go应用构建使用的任何CI服务器或私有仓库进行对接。而使用JFrog CLI和Artifactory,可以使得这一过程更加便捷。

想要了解有关 GoCenter 更多深入的技术信息?请查看GoCenter的Github项目,https://github.com/jfrog/gocenter


八、参考文献

Golanghttps://golang.org

Go & Versioning: https://research.swtch.com/vgo

GoCenterhttps://gocenter.io/

          https://github.com/jfrog/gocenter

goc https://github.com/jfrog/goc

JFrog CLI:https://www.jfrog.com/confluence/display/CLI/CLI+for+JFrog+Artifactory

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 备注:本猿翻译水平有限,请各位看客见谅 翻译内容: go1.11 版本中 go help modules文档内容 ...
    星云数联阅读 2,502评论 0 1
  • Golang具有一套可以构建和处理go源代码的程序,作为命令行工具,这些程序也并非直接运行,而是由go程序调用。运...
    云时代的运维开发阅读 3,421评论 0 0
  • 包管理的重要性不言而喻。随着项目的推进,没有合适的包管理,每一次迭代都将成为开发者的噩梦。尤其是对于进行持续集成的...
    suoga阅读 4,450评论 4 10
  • 摘自《海外星云》2006年第35期 7年前,岳母的肾脏出了问题,必须洗肾。当时,岳母的情绪非常低落,过了几天,岳父...
    水木的小院阅读 266评论 0 1
  • 1.诊断。诊断评估最重要。要多元立体的积累。融会贯通。芒格的思维模型。连接感。世界是互相联系多元的。 2.价值第一...
    笃信_241534阅读 182评论 0 0