搭建可维护的Golang开发环境

本篇文章将聊聊如何快速搭建 Linux 环境中的 Golang 开发环境。

《基础篇》[1]的内容中,我们聊过了如何基于 Ubuntu 22.04 搭建基础的 Linux 学习环境。接下来的文章里,我们先来聊聊如何在 Linux 环境中,快速安装配置各种可维护的语言环境。

写在前面

在开始聊如何做之前,我们首先要了解为什么要这么做。

我知道有不少同学有安装好环境之后,然后持续使用一个环境,并天长地久的用下去的习惯。这样做的好处是看起来简单省心,但实际上却埋藏了许多隐患,举几个常见的例子:

  • 同事说代码、程序有问题,跑不起来,你说程序在你这边是正常的,你觉得他的使用方式不对,他觉得你的程序兼容性/健壮性有问题。•当你想把半年、一年前的项目跑起来,发现运行的时候多了非常多的警告,甚至是报错,尤其是当你换了一台电脑的时候。
  • 项目扩充人手,你的同事也需要配置一套环境,你和他折腾的半天,虽然有着重重困难,什么版本不对,配置散落在系统的各个犄角旮旯等等,但是你们最终克服了困难,并加深了革命友情。
  • 项目遇到大版本升级,因为一些历史原因,你需要同时使用两个不同的语言版本来做调试,不同版本存在兼容性问题(包括依赖兼容性问题),你的本地环境是升级还是不升呢。

解决这个问题的最佳方案有两个:

  • 尽可能简化你的环境,简化环境依赖(因为项目的多样性和复杂性,这有一些难)。
  • 尽可能参考基础架构即代码(IaC)的思想去维护我们自己的开发环境,让我们所使用的内容,尽可能配置化,透明化,可复现

它除了能够完成 golang 开发环境的快速安装之外,还能够保障多个版本的 golang 共存,不同版本的软件依赖包都保持正常工作。并且,它的实现和社区大名鼎鼎的 nvm-sh/nvm 、shyiko/jabba 是一致的,都是由 BASH 编写,和所需要管理的 Runtime 语言无关,能够更稳定的完成管理工作。

Golang 环境安装和配置使用

关于 Golang 的多版本管理和安装,我曾经写过两篇相关的内容,一篇是半年前的内容,分享如何对Golang 进行多版本管理[2],另外一篇则是这篇的补充内容,分享如何针对 Mac M1 这类 ARM 设备使用 Golang 版本管理工具:《M1 芯片 Mac 上更好的 Golang 使用方案》[3]

如果你希望了解本章节之外的实践内容,或者过程中的思考,可以翻阅上面两篇内容。本篇文章的重点在于如何快速安装和配置,所以就不再展开相关折腾安装工具的细节啦。

安装 Golang 版本管理工具:soulteary/gvm

关于 Golang 的安装和版本升降级,因为老牌开源软件 GVM (Go Version Manager)年久失修,所以我做了一个修正版:https://github.com/soulteary/gvm

想要正常使用这个工具,我们需要先完成工具的基础依赖的安装:

sudo apt install -y binutils bison gcc make

接着,执行下面的命令,通过网络获取安装脚本,然后在本地执行脚本完成安装。(如果你因为网络或其他原因,无法执行这条命令,可以使用下文中的替代方案):

curl -sSL https://github.com/soulteary/gvm/raw/master/binscripts/gvm-installer|bash

不出意外的话,你将会看到类似下面的日志输出,意味着工具就此刻已经安装好啦。

Cloning from https://github.com/soulteary/gvm.git to /home/soulteary/.gvm
No existing Go versions detected
Installed GVM v1.0.24

Please restart your terminal session or to get started right away run`source/home/soulteary/.gvm/scripts/gvm`

这里选择执行或者不执行source /home/soulteary/.gvm/scripts/gvm这条命令都可以(注意调整路径中的用户名),因为在接下来的文章中,我们将使用更靠谱的方式来将命令注册到我们所使用的 SHELL 环境中。

使用国内镜像来安装:soulteary/gvm

为了让安装过程更加顺利,我们可以使用从国内镜像下载包含安装脚本的仓库代码,然后直接执行安装脚本,来完成gvm这个开源软件的安装。

先使用git clone下载完整的软件仓库:

git clone https://gitcode.net/soulteary/gvm.git

指定SRC_REPO参数为国内镜像地址,然后运行安装脚本:

SRC_REPO=https://gitcode.net/soulteary/gvm.git bash gvm/binscripts/gvm-installer

当脚本运行完毕,我们将会看到上文中提到过的日志输出,此刻gvm就安装完毕啦。

Cloning from https://gitcode.net/soulteary/gvm.git to /home/soulteary/.gvm
No existing Go versions detected
Installed GVM v1.0.24

Please restart your terminal session or to get started right away run`source/home/soulteary/.gvm/scripts/gvm`

为了更方便的使用gvm,我们还需要进行一些配置。

配置 gvm 加速 Golang 下载/切换

gvm 支持使用两种方式来下载 Golang,然而不论是下载源码编译安装,还是下载适合当前操作系统的预编译好的二进制文件,我们都需要访问官方地址。

为了避免下载过程中因为网络问题,出现下载慢,或者无法下载的情况,节约我们的时间,我们需要对gvm进行一些简单的配置。

我们可以在当前使用的SHELLrc文件中(比如.bashrc或者.zshrc),添加下面的内容,来在当前的环境中让gvm命令生效,同时,让我们能够使用更快的下载源来下载我们所需要的 Golang:

exportGO_BINARY_BASE_URL=https://golang.google.cn/dl/[[-s"$HOME/.gvm/scripts/gvm"]]&&source"$HOME/.gvm/scripts/gvm"exportGOROOT_BOOTSTRAP=$GOROOT

rc文件中添加了上述内容后,需要重启终端会话,才能够让会话生效。你可以使用CTRL+D退出登录,然后再重新使用SSH进行终端连接或者直接在本地创建一个新的会话(具体怎么做,取决于你是如何开启的会话)。

为了让配置过程清晰透明,上面的三条命令,我们来依次看看上面的命令都做了什么事情。

exportGO_BINARY_BASE_URL=https://golang.google.cn/dl/

命令中的GO_BINARY_BASE_URL变量,定义了我们将从何处下载 Golang 的二进制文件或源码压缩包进行安装。当然,你也可以将其替换为下面的任意一个。

官方地址https://go.dev/dl/官方国内镜像地址https://golang.google.cn/dl/阿里云镜像https://mirrors.aliyun.com/golang/中科大镜像http://mirrors.ustc.edu.cn/golang/

接下来,我们来看看三条命令中看似最复杂的命令:

[[-s"$HOME/.gvm/scripts/gvm"]]&&source"$HOME/.gvm/scripts/gvm"

这条命令,是根据软件的实际安装情况来选择性加载gvm。相比较前文中安装完毕gvm日志输出内容推荐我们直接使用source命令加载gvm,这样可以更安全的执行命令,当且仅当~/.gvm存在的时候才会加载程序,将gvm注册到你当前的SHELL环境中。

exportGOROOT_BOOTSTRAP=$GOROOT

最后一条命令,则是为了确保 Golang 使用源码编译安装时,不会出错(golang 1.14后需要 ),感兴趣可以围观官方开源项目中的这个 issue[4]

gvm 简明实用教程

gvm是一个特别简单的命令,我们日常使用中其实只需要记得两个命令就好,第一个是gvm install,第二个是gvm use

假设我们想安装 Golang 最新版本 1.18.3,那么只需要执行下面的命令:

gvm install go1.18.3 -B

在执行完毕命令之后,稍等片刻,当我们看到Installing go1.18.3 from binary source这条日志输出结果后,就意味着 Golang 已经被下载完毕了。如果你希望使用编译源码的方式安装 Golang 的话,可以去掉上面命令中的-B参数:

gvm install go1.18.3

虽然我们已经完成了 Golang 1.18.3 的安装,但是目前我们还不能直接使用它,需要再执行一条命令,将这个版本的 Golang 激活:

gvm use go1.18.3 --default

在执行完命令之后,我们能够立刻看到类似Now using version go1.18.3的日志输出结果,接下来我们就可以随意的使用go这个命令了。

我们可以使用go version来验证刚刚下载的程序是否符合我们的诉求:

go version
go version go1.18.3 linux/amd64

未来如果 Golang 推出了新版本,我们想升级只需要按照上面的玩法,调整版本号,然后再执行一遍installuse命令就好了,是不是很简单!

当然,如果你只是想临时性的使用某个版本,比如 Golang 1.17 这个旧版本,可以稍微调整一下上面的命令,去掉use命令中的--default参数,只在当前SHELL会话中,让这个版本的 Golang 生效,随着我们关闭终端会话,Golang 的版本也会恢复到我们指定的默认版本,再也不需要担心系统环境混乱的问题啦。

gvm install go1.17 -B
gvm use go1.17再次执行查看版本,可以看到版本号已经变化了go version
go version go1.17 linux/amd64

配置 Golang 软件包镜像

在日常开发和学习过程中,我们更多的是使用 Golang 来初始化项目和下载必要的软件包依赖。所以如何快速的下载到各种软件包也很重要,好在 Golang 提供了软件包代理配置选项GOPROXY,我们可以通过在SHELLrc文件中配置这个参数来完成下载提速:

exportGO111MODULE=onexportGOPROXY="https://goproxy.cn"

和上文中配置gvm一样,我们将上面的内容添加到所使用的 SHELL 的rc配置后,需要重新创建一个终端会话,让配置生效。

当然,你也可以将上面命令中使用的镜像源替换为下面任意一个:

由七牛云赞助的项目goproxy.cn阿里云https://mirrors.aliyun.com/goproxy/华为云https://repo.huaweicloud.com/repository/goproxy/一家的goproxy.io
proxy.golang.com.cn

这里有一个题外话,初见goproxy的两个域名的时候,觉得域名十分相似,一番搜索,发现这两个域名虽然归属不同的开发者在维护,但是它们之间确实有一段缘分:goproxy.io 和 goproxy.cn 的关系[5]

Golang 环境验证:GoJieba

在完成环境配置之后,我们使用一个比较实用的 Golang 项目(https://github.com/yanyiwu/gojieba),来验证环境是否好用。

随便创建一个程序目录,然后在其中创建一个名为main.go的文件,引用 gojieba,并对一些句子和词汇进行处理:

packagemainimport("fmt""strings""github.com/yanyiwu/gojieba")funcmain(){varsstringvarwords[]stringuse_hmm:=truex:=gojieba.NewJieba()deferx.Free()s="北京西站南广场东"words=x.CutAll(s)fmt.Println(s)fmt.Println("全模式:",strings.Join(words,"/"))words=x.Cut(s,use_hmm)fmt.Println(s)fmt.Println("精确模式:",strings.Join(words,"/"))s="向量数据库"words=x.Cut(s,use_hmm)fmt.Println(s)fmt.Println("精确模式:",strings.Join(words,"/"))x.AddWord("向量数据库")s="向量数据库"words=x.Cut(s,use_hmm)fmt.Println(s)fmt.Println("添加词典后,精确模式:",strings.Join(words,"/"))s="前门到了,请您后门下车"words=x.Cut(s,use_hmm)fmt.Println(s)fmt.Println("新词识别:",strings.Join(words,"/"))s="小明先去了北京西站南广场东,然后又去了南京东路北大街西"words=x.CutForSearch(s,use_hmm)fmt.Println(s)fmt.Println("搜索引擎模式:",strings.Join(words,"/"))s="朝阳区三里屯优衣库"words=x.Tag(s)fmt.Println(s)fmt.Println("词性标注:",strings.Join(words,","))s="元宇宙"words=x.Tag(s)fmt.Println(s)fmt.Println("词性标注:",strings.Join(words,","))s="长江大桥"words=x.CutForSearch(s,!use_hmm)fmt.Println(s)fmt.Println("搜索引擎模式:",strings.Join(words,"/"))wordinfos:=x.Tokenize(s,gojieba.SearchMode,!use_hmm)fmt.Println(s)fmt.Println("Tokenize:(搜索引擎模式)",wordinfos)wordinfos=x.Tokenize(s,gojieba.DefaultMode,!use_hmm)fmt.Println(s)fmt.Println("Tokenize:(默认模式)",wordinfos)keywords:=x.ExtractWithWeight(s,5)fmt.Println("Extract:",keywords)}

在准备好程序文件之后,我们先执行go mod init main,完成 Go 项目的初始化:

go: creating new go.mod: module main
go: to add module requirements and sums:
    go mod tidy

在执行完上面的命令后,我们的目录中将会多出来 go.mod 和 go.sum 两个文件,接着,我们来执行go mod tidy命令,让程序完成相关依赖的下载:

go: finding moduleforpackage github.com/yanyiwu/gojieba
go: found github.com/yanyiwu/gojieba in github.com/yanyiwu/gojieba v1.1.2

因为我们配置了软件包镜像,所以应该在几秒内就能够完成项目的初始化。

在完成了项目初始化之后,我们执行go run main.go来验证下程序是否能运行,不出意外,将看到类似下面的输出结果:

北京西站南广场东
全模式: 北京/北京西/北京西站/京西/西站/南/广场/东
北京西站南广场东
精确模式: 北京西站/南/广场/东
向量数据库
精确模式: 向量/数据库
向量数据库
添加词典后,精确模式: 向量数据库
前门到了,请您后门下车
新词识别: 前门/到/了/,/请/您/后门/下车
小明先去了北京西站南广场东,然后又去了南京东路北大街西
搜索引擎模式: 小明/先去/了/北京/京西/西站/北京西/北京西站/南/广场/东/,/然后/又/去/了/南京/京东/东路/南京东路/北大/大街/北大街/西
朝阳区三里屯优衣库
词性标注: 朝阳区/ns,三里屯/ns,优衣库/x
元宇宙
词性标注: 元/m,宇宙/n
长江大桥
搜索引擎模式: 长江/大桥/长江大桥
长江大桥
Tokenize:(搜索引擎模式) [{长江 0 6} {大桥 6 12} {长江大桥 0 12}]
长江大桥
Tokenize:(默认模式) [{长江大桥 0 12}]
Extract: [{长江大桥 11.1926274509}]

当然,除了run之外,我们最常用的命令还有testbuild,本篇文章暂时不聊如何写单元测试,所以我们就先只验证build命令,执行go build .,我们将在程序目录得到一个名为main的可执行文件。

手动执行命令./main,不出意外,将得到和上面run一样的输出结果。至此,Golang 环境验证也就结束啦。

最后

目前为止,我们已经聊完了基础 Linux 环境搭建、Docker 环境安装和配置、Golang 的开发环境搭建。

接下来的文章中,我会继续完成上篇文章中提到的几种不同的 K8S 发行版的安装和配置,以及当今世界上流行的编程语言的环境配置。

希望对你有帮助。

–EOF


引用链接

[1]《基础篇》:https://soulteary.com/2022/06/21/building-a-cost-effective-linux-learning-environment-on-a-laptop-the-basics.html[2]Golang 进行多版本管理:https://soulteary.com/2021/12/15/golang-multi-version-management.html[3]《M1 芯片 Mac 上更好的 Golang 使用方案》:https://soulteary.com/2022/05/12/better-golang-usage-on-m1-mac.html[4]这个 issue:https://github.com/golang/go/issues/12214[5]goproxy.io 和 goproxy.cn 的关系:https://github.com/goproxy/goproxy.cn/issues/61


如果你觉得内容还算实用,欢迎点赞分享给你的朋友,在此谢过。

如果你想更快的看到后续内容的更新,请戳点赞、分享、喜欢,这些免费的鼓励将会影响后续有关内容的更新速度。


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。署名 4.0 国际 (CC BY 4.0)[6]

本文作者: 苏洋

创建时间: 2022年07月04日 统计字数: 8072字 阅读时间: 17分钟阅读 本文链接:https://soulteary.com/2022/07/04/build-a-maintainable-golang-development-environment.html

原创文章 搭建可维护的Golang开发环境,版权所有
如若转载,请注明出处:https://www.itxiaozhan.cn/202210534.html

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注