Go Modules 的前世今生
2022-4-12 17:4:56 Author: mp.weixin.qq.com(查看原文) 阅读量:4 收藏

头两天看到组里头的老师傅在学 Golang,忙里偷闲,花了点时间也浅学一下。

0x01 什么是 Go Modules?

Go Modules 是 Go 语言的依赖解决方案,发布于 Go 1.11,成长于 Go 1.12,丰富于 Go 1.13,正式于 Go 1.14 推荐在生产环境上使用。

Go Modules 目前集成在 Go 的工具链中,只要安装了 Go,自然而然地也就可以使用 Go Modules 了,而 Go Modules 的出现也解决了在 Go 1.11 前的几个常见争议问题:

  1. Go 语言长久以来的依赖管理问题
  2. “淘汰”现有的 GOPATH 的使用模式
  3. 统一社区中的其他依赖管理工具(提供迁移功能)

0x02 GOPATH 是什么及 GOPATH 的工作模式

Go Moudles 的目的之一就是淘汰 GOPATH,那么 GOPATH 是个什么呢?

为什么在 GO 1.11 前就使用 GOPATH,而 GO 1.11 之后就开始逐步建议使用 Go Modules,不再推荐 GOPATH 的模式了呢?

image
image

0x03 GOPATH 工作模式的弊端

  1. 无版本控制概念
  2. 无法同步一致第三方版本号
  3. 无法指定当前项目引用的第三方版本号

0x04 Go Modules 模式基础环境说明

采用 Go Modules 的模式创建一个项目,为了区分 GOPATH,项目创建在非 $GOPATH/src 下。

一、go mod 命令

image
命令说明
go mod init生成 go.mod 文件
go mod download下载 go.mod 文件中指明的所有依赖
go mod tidy整理现有的依赖
go mod graph查看现有的依赖结构
go mod edit编辑 go.mod 文件
go mod vendor导出项目的所有依赖到 vendor 目录
go mod verify校验一个模块是否被篡改过
go mod why查看为什么需要依赖某模块

二、go mod 环境变量

通过 go env 命令进行查看:

set GO111MODULE=on
set GOPROXY=https://goproxy.cn,direct
set GONOPROXY=
set GOSUMDB=sum.golang.org
set GONOSUMDB=
set GOPRIVATE=

GO111MODULE

Go 语言提供了 GO111MODULE 这个环境变量作为 Go Modules 的开关,其允许设置以下参数:

  • auto:只要项目包含了 go.mod 文件就启用 Go Modules,目前在 Go 1.11 至 Go 1.14 中仍然是默认值
  • on:启用 Go Modules,推荐设置,将会是未来版本中的默认值
  • off:禁用 Go Modules,不推荐设置

可以通过 go env 命令来设置:

go env -w GO111MODULE=on

GOPROXY

这个环境变量主要用于设置 Go 模块代理(Go Module Proxy),其作用是用于使 Go 在后续拉取模块版本时直接通过镜像站点来快速拉取。

GOPROXY 的默认值是:https://proxy.golang.org,direct

proxy.golang.org 国内无法访问,需要设置代理。

  • 阿里云:https://mirrors.aliyun.com/goproxy/
  • 七牛云:https://goproxy.cn,direct

如:

go env -w GOPROXY=https://goproxy.cn,direct

GOSUMDB

它的值是一个 Go checksum database,用于在拉取模块版本时(无论是从源站拉取,还是通过 Go Module Proxy 拉取),保证拉取到的模块版本数据未经篡改,若发现不一致,也就有可能存在篡改,将会立即终止。

GOSUMDB 的默认值是 sum.golang.org,在国内也是无法访问的,但是 GOSUMDB 可以被 Go 模块代理所代理(参考:Proxying a Checksum Database)。

image

因此,我们可以通过设置 GOPROXY 来解决,而先前我们所设置的模块代理 goproxy.cn 就能支持代理 sum.golang.org,所以这一个问题在设置了 GOPROXY 后,我们无需过度关心。

另外若对 GOSUMDB 的值有自定义需求,其支持格式如下:

  • 格式 1:<SUMDB_NAME>+<PUBLIC_KEY>
  • 格式 2:<SUMDB_NAME>+<PUBLIC_KEY> <SUMDB_URL>

也可将其设置为“off”,也就是禁止 Go 在后续操作中校验模块版本。

GONOPROXY/GONOSUMDB/GOPRIVATE

这三个环境变量都是用在当前项目依赖私有模块,例如公司内部的私有 Git 仓库,或者 Github 中的私有仓库,均属于私有模块,需要设置对应的环境变量,否则则会拉取失败。

更细致来讲,就是依赖了由 GOPROXY 指定的 Go 模块代理,或由 GOSUMDB 指定 Go Checksums Database 都无法访问到的模块时的场景。

一般建议直接设置 GOPRIVATE,它的值将作为 GONOPROXY 和 GONOSUMDB 的默认值,所以建议直接使用 GOPRIVATE。

并且它们的值都是一个以英文逗号“,”分割的模块路径前缀,也就是可以设置多个,例如:

go env -w GOPRIVATE="git.example.com,github.com/tonghuaroot/S3OSINT"

环境变量设置后,前置为 git.example.com 和 github.com/tonghuaroot/S3OSINT 的模块均将被识别为私有模块。

如果不想每次都重新设置,我们也可以使用通配符,如:

go env -w GOPRIVATE="*.example.com"

此时所有模块路径为 example.com 的子域名均将不经过 Go Module Proxy 和 Go Checksum Database,需要注意的是不包括 example.com 本身。

0x05 使用 Go Modules 初始化项目

创建测试目录:

mkdir modules_test
cd modules_test
pwd -> D:\Users\tongh\go\src\github.com\tonghuaroot\modules_test

初始化 Go Modules 模块:

go mod init
# or
go mod init <当前项目名称,如 github.com/tonghuaroot/modules_test>
image
image

创建测试入口文件:

package main

import (
 "fmt"
 "github.com/aceld/zinx/ziface"
 "github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
 znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
 // 读取客户端数据
 fmt.Println("recv from client : msgId = ", request.GetMsgID(), ", data = ", string(request.GetData()))

 // 回写 ping
 err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping..."))

 if err != nil {
  fmt.Println(err)
 }
}

func main() {
 // 1. 创建 server 句柄
 s := znet.NewServer()

 // 2. 配置路由
 s.AddRouter(0, &PingRouter{})

 // 3. 开启服务
 s.Serve()
}

go fmt
go get github.com/aceld/zinx/ziface
go get github.com/aceld/zinx/znet
go run main.go # 直接运行该命令,Golang 也会自动下载相关依赖

相关依赖的存储位置:$GOPATH/pkg/mod

image
image
image

0x06 改变模块依赖关系

修改依赖模块的版本号:

go mod edit -replace="[email protected]"="[email protected]"
image

0x07 导出依赖至 vendor 目录

go mod vendor
image

0x08 总结

学一下 Go Modules 相关内容并记录了一下。

0x09 References

  1. https://www.bilibili.com/video/BV1gf4y1r79E?p=36&spm_id_from=pageDriver
  2. https://go.dev/ref/mod

文章来源: https://mp.weixin.qq.com/s?__biz=Mzg5NjAxNjc5OQ==&mid=2247483865&idx=1&sn=d2b4401da7ae446ea7c2ae5a65632dad&chksm=c006c929f771403fd9f7d4915a1cadabf6ab53e6382449427ab7d0f351349e7de2c8cd877dea&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh