头两天看到组里头的老师傅在学 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 Moudles 的目的之一就是淘汰 GOPATH,那么 GOPATH 是个什么呢?
为什么在 GO 1.11 前就使用 GOPATH,而 GO 1.11 之后就开始逐步建议使用 Go Modules,不再推荐 GOPATH 的模式了呢?
采用 Go Modules 的模式创建一个项目,为了区分 GOPATH,项目创建在非 $GOPATH/src
下。
命令 | 说明 |
---|---|
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 的开关,其允许设置以下参数:
可以通过 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)。
因此,我们可以通过设置 GOPROXY 来解决,而先前我们所设置的模块代理 goproxy.cn 就能支持代理 sum.golang.org,所以这一个问题在设置了 GOPROXY 后,我们无需过度关心。
另外若对 GOSUMDB 的值有自定义需求,其支持格式如下:
也可将其设置为“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>
创建测试入口文件:
package mainimport (
"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
修改依赖模块的版本号:
go mod edit -replace="[email protected]"="[email protected]"
go mod vendor
学一下 Go Modules 相关内容并记录了一下。