Go Module - luyaops/fw GitHub Wiki

在项目中使用 Go Module

从1.11开始支持go modules机制。这个机制起到了项目的版本控制目的。并且会在1.13开始默认开启。

目前的版本是需要手工开启go modules。

修改/etc/profile,开启go modules和GOPOXY(速度很快,不用纠结包的下载):

export GOPATH=/home/adrootrr/opt/go                
export GOROOT=/usr/local/go
export GOTOOLS=$GOROOT/pkg/tool
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# Enable the go modules feature
export GO111MODULE=on
# Set the GOPROXY environment variable
export GOPROXY=https://goproxy.io
执行:
source /etc/profile

go mod命令

download    download modules to local cache (下载依赖的module到本地cache))
edit        edit go.mod from tools or scripts (编辑go.mod文件)
graph       print module requirement graph (打印模块依赖图))
init        initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件))
tidy        add missing and remove unused modules (增加丢失的module,去掉未用的module)
vendor      make vendored copy of dependencies (将依赖复制到vendor下)
verify      verify dependencies have expected content (校验依赖)
why         explain why packages or modules are needed (解释为什么需要依赖)

开始 go module后。gopath原来的src作用就没有了。go get下载的包都会在$GOPATH/pkg/mod/,install的二进制文件还是在$GOPATH/bin。 现在自己的项目就可以脱离gopath了。

下面我演示下本仓库的项目用go modules搭建起来

不用go get来下代码了。因为在src里不会有了。直接clone luyaops的仓库

# 项目目录可以任意
mkdir -p GoProjects/luyaops
cd GoProjects/luyaops
# 拉取远程代码:
git clone https://github.com/luyaops/api-gateway.git
git clone https://github.com/luyaops/example.git
git clone https://github.com/luyaops/fw.git
git clone https://github.com/luyaops/cmdb.git

打开goland,据说目前ide支持gomodule的最好的就是goland

Goland:file ==> settings==> Go

代理用https://goproxy.io.

初始化: 分别进入4个仓库中。执行

go mod init

生成以下文件。

./api-gateway/go.mod
./fw/go.mod
./example/go.mod
./cmdb/go.mod

在4个仓库里执行

整理依赖包
go mod tidy
会输出提示
go: finding github.com/gogo/protobuf/proto latest
go: finding github.com/luyaops/fw/common/etcd latest
go: finding github.com/luyaops/fw/core latest
go: finding github.com/luyaops/fw/common/constants latest
go: finding github.com/luyaops/fw/common/log latest
go: finding github.com/luyaops/fw/common/config latest
go: finding google.golang.org/grpc v1.21.0
...

如果想缓存到vendor目录

go mod vendor

第一次执行依赖包会比较多。所以用时比较长。实在等不起断掉过一会再执行。
或者手工按照自己需要的包去一个一个的go get -u xxxx/xxx,个人感觉这样比较快,可能用go mod tidy他还有一些其他的操作什么的。
go get 的时候在你的项目下执行。有生成go.mod的那个目录。modules模式下go get也是根据go env使用proxy的。

还有一种简单的方法。用goland ide的提示。

选择sync packages from xxxx。。。
哪里缺包点哪里~~!我的经验是:如果耗时过长就中断重新来一次

然后你会发现一开始go.mod文件把依赖都记录下来了,后面是indirect的代表间接引用的。并且会生成一个go.sum记录每个依赖库的版本和哈希值

module github.com/luyaops/api-gateway

go 1.12

require (
	github.com/coreos/bbolt v1.3.2 // indirect
	github.com/coreos/etcd v3.3.13+incompatible // indirect
	github.com/coreos/go-semver v0.3.0 // indirect
	github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
	github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
	github.com/gogo/protobuf v1.2.1
	github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect
	github.com/google/btree v1.0.0 // indirect
	github.com/gorilla/websocket v1.4.0 // indirect
	github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
	github.com/grpc-ecosystem/grpc-gateway v1.9.0 // indirect
	github.com/jonboulle/clockwork v0.1.0 // indirect
	github.com/json-iterator/go v1.1.6 // indirect
	github.com/luyaops/example v0.0.0-20190528060856-149ebc37a966
	github.com/luyaops/fw v0.0.0-20190528065857-928999e37638
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/modern-go/reflect2 v1.0.1 // indirect
	github.com/prometheus/client_golang v0.9.3 // indirect
	github.com/soheilhy/cmux v0.1.4 // indirect
	github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
	go.etcd.io/bbolt v1.3.2 // indirect
	go.etcd.io/etcd v3.3.13+incompatible
	go.uber.org/atomic v1.4.0 // indirect
	go.uber.org/multierr v1.1.0 // indirect
	go.uber.org/zap v1.10.0 // indirect
	golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
	google.golang.org/grpc v1.21.0
)

依赖用本地包

看到上面有个问题。依赖里面有两条本地包。如果不用本地那需要在github上有修改然后再拉取。

	github.com/luyaops/example v0.0.0-20190528060856-149ebc37a966
	github.com/luyaops/fw v0.0.0-20190528065857-928999e37638

所以咱们修改go.mod,用它的replace,在go.mod中添加

replace (
	github.com/luyaops/example => /home/adrootrr/GoProjects/luyaops/example
	github.com/luyaops/fw => /home/adrootrr/GoProjects/luyaops/fw
)

然后go.mod突然自己就变了。吓我一跳。不过好似没有问题。它自己检查的

module github.com/luyaops/api-gateway

go 1.12

require (
	github.com/gogo/protobuf v1.2.1
	github.com/luyaops/example v0.0.0-20190528060856-149ebc37a966
	github.com/luyaops/fw v0.0.0-20190528065857-928999e37638
	go.etcd.io/etcd v3.3.13+incompatible
	google.golang.org/appengine v1.4.0 // indirect
	google.golang.org/grpc v1.21.0
)

replace (
	github.com/luyaops/example => /home/adrootrr/GoProjects/luyaops/example
	github.com/luyaops/fw => /home/adrootrr/GoProjects/luyaops/fw
)

最后一个问题

ide的这个提示不需要更新。但是需要更新makefile文件里的搜索路径来生成proto。

api-gateway:


{"level":"info","time":"2019-06-04T07:57:05.974-0700","caller":"/home/adrootrr/GoProjects/luyaops/api-gateway/cmd/main.go:11","msg":"API gateway start"}
{"level":"info","time":"2019-06-04T07:57:05.996-0700","caller":"/home/adrootrr/GoProjects/luyaops/api-gateway/loader/load.go:42","msg":"Registration information loaded successfully"}
{"level":"info","time":"2019-06-04T07:57:05.996-0700","caller":"/home/adrootrr/GoProjects/luyaops/api-gateway/server/forward.go:18","msg":"Listening on 0.0.0.0:8080"}

example:

{"level":"info","time":"2019-06-04T07:59:54.866-0700","caller":"/home/adrootrr/GoProjects/luyaops/fw/core/run.go:31","msg":"Listening on 0.0.0.0:50051"}