Go工程化实践之包管理
包管理
Go Package 管理发展史
Go 依赖管理是通过 Git 仓库模式实现,并随着版本的更迭已经逐渐完善。
GOPATH 模式
GOPATH 目录是所有工程的公共依赖包目录,所有需要编译的 go 工程的依赖包都放在 GOPATH 目录下。
Vendor 特性
为了解决 GOPATH 模式下,多个工程需要共享 GOPATH 目录,无法适用于各个工程对于不同版本的依赖包的使用,不便于更新某个依赖包。
go 1.6之后开启了vendor目录Go Module 包管理
从
GO 1.11以后开始支持Module依赖管理工具,从而实现了依赖包的升级更新,在GO 1.13版本后默认打开
GOPATH 环境变量
GOPATH 为 Go 开发环境时所设置的一个环境变量。
历史版本的 go 语言开发时,需要将代码放在 GOPATH 目录的 src 文件夹下。go get 命令获取依赖,也会自动下载到 GOPATH 的 src 下。
1 | go get github.com/foo/bar |
会将代码下载到 $GOPATH/github.com/foo/bar
GOPATH 具体结构如下,必须包含三个文件夹,具体如下图所示:
1 | GOPATH |
Using Go Modules
Go Modules 是从 Go 1.11 开始初步支持,解决了依赖版本的信息管理,并且保证安全性。
主要通过 go.mod 和 go.sum 组成,主要包括依赖模块路径定义,以及通过 checksum 方式进行保证包的安全性。并且可以在 GOPATH 外进行创建和编译项目。
通过 go mod init xxx 初始化一个项目

使用时
1 | package main |
通过 go get github.com/sirupsen/logrus ,可以下载或者更新依赖包,也可以指定版本 path@v1.8.1

go.mod 文件中可以使用到的语法关键词以及含意:
module:定义当前项目的模块路径go:标识当前模块的GO语言版本,目前来看还只是个标识作用require:说明Module需要什么版本的依赖exclude:用于从使用中排除一个特定的模块版本replace:替换require中声明的依赖,使用另外的依赖及其版本号

Go Modules Checksum
为了解决 Go Modules 的包被篡改安全隐患,Go 开发团队在引入 go.mod 的同时也引入了 go.sum 文件,用于记录每个依赖包的哈希值,在构建时,如果本地的依赖包 hash 值与 go.sum 文件中记录的不一致,则会拒绝构建。
go.sum文件中每行记录由 module 名、版本和哈希组成,并由空格分开;- 在引入新的依赖时,通常会使用
go get命令获取该依赖,将会下载该依赖包下载到本地缓存目录$GOPATH/pkg/mod/cache/download,该依赖包为一个后缀为.zip的压缩包,并且把哈希运算同步到go.sum文件中; - 在构建应用时,会从本地缓存中查找所有
go.mod中记录的依赖包,并计算本地依赖包的哈希值,然后与go.sum中的记录进行对比,当校验失败,go 命令将拒绝构建。
Go Modules Proxy
Go 1.13 将 GOPROXY 默认成了中国大陆无法访问的 https://proxy.golang.org,所以在国内需要配置代理进行使用。
GOPROXY 可以解决一些公司内部的使用问题:
- 访问公司内网的
git server - 防止公网仓库变更或者消失,导致线上编译失败或者紧急回退失败
- 公司审计和安全需要
- 防止公司内部开发人员配置不当造成
import path泄露 - cache 热点依赖,降低公司公网出口带宽

Go Modules Private
GOPRIVATE 用来控制 go 命令把哪些仓库看作是私有的仓库,这样可以跳过 proxy server 和校验检查,这个变量的值支持用逗号分隔,可以填写多个值,例如:
1 | export GOPRIVATE=*.corp.example.com,github.com/org_name |
当配置 GOPROVATE,它的值同时也将作为 GONOPROXY 和 GONOSUMDB 的默认值,所以当配置 GOPRIVATE 后将会跳过代理,以及 checksum 校验检查。
通常推荐配置 GOPROXY 和 GOPRIVATE 进行使用,GOPRIVATE 也可以识别 Git SSH KEY 进行权限校验。
GOPROXY 编译部署
goproxy.io 是一个 Go Modules 开源代理,也可以作为公司内部代理。
https://github.com/goproxyio/goproxy
1 | 下载以及编译 |
GOPROXY 配置信息
goproxy 运行配置信息:
1 | ./goproxy --help |
GOPROXY 访问内网仓库
goproxy 配置访问公司内网的 git server:
- 用户本地配置
GONOSUMDB=github.com/private - goproxy server 配置 exclude 进行排除掉所代理仓库
- goproxy server 配置 SSH Key ,并且在仓库添加只读权限
- goproxy server 配置 .gitconfig 把 ssh 替换成 http 方式访问

推荐 proxy
https://goproxy.io
https://github.com/gomods/athens
https://goproxy.cn
参考
Go Modules Reference
Go Modules in 2019
Using Go Modules
Migrating to Go Modules
Module Mirror and Checksum Database Launched
Publishing Go Modules
Go Modules: v2 and Beyond
Keeping Your Modules Compatible