头两天看到组里头的老师傅在学 Golang,忙里偷闲,花了点时间也浅学一下。
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 前的几个常见争议问题:
Go 语言长久以来的依赖管理问题
“淘汰”现有的 GOPATH 的使用模式
统一社区中的其他依赖管理工具(提供迁移功能)
Go Moudles 的目的之一就是淘汰 GOPATH,那么 GOPATH 是个什么呢?
为什么在 GO 1.11 前就使用 GOPATH,而 GO 1.11 之后就开始逐步建议使用 Go Modules,不再推荐 GOPATH 的模式了呢?
image
image
无版本控制概念
无法同步一致第三方版本号
无法指定当前项目引用的第三方版本号
采用 Go Modules 的模式创建一个项目,为了区分 GOPATH,项目创建在非 $GOPATH/src
下。
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 env
命令进行查看:
set GO111MODULE=on
set GOPROXY=https://goproxy.cn,direct
set GONOPROXY=
set GOSUMDB=sum.golang.org
set GONOSUMDB=
set GOPRIVATE=
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
这个环境变量主要用于设置 Go 模块代理(Go Module Proxy),其作用是用于使 Go 在后续拉取模块版本时直接通过镜像站点来快速拉取。
GOPROXY 的默认值是:https://proxy.golang.org,direct
proxy.golang.org 国内无法访问,需要设置代理。
如:
go env -w GOPROXY=https://goproxy.cn,direct
它的值是一个 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 在后续操作中校验模块版本。
这三个环境变量都是用在当前项目依赖私有模块,例如公司内部的私有 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 本身。
创建测试目录:
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
修改依赖模块的版本号:
go mod edit -replace="zinx@v1.0.1"="zinx@v1.0.0"
image
go mod vendor
image
学一下 Go Modules 相关内容并记录了一下。