记一下学习上古Go-Micro手配环境踩到的坑

由于已经配过了go-proxy,所以跑go get没任何问题,因此解决了大半难题

具体环境如下:

  • Windows 10 20H2 19042.1237
  • GoLand 2021.2.1
  • GOVERSION=go1.16.7
  • GO111MODULE=on
  • GOPROXY=https://goproxy.cn
  • Consul v1.10.2
  • mingw32-gcc.exe (tdm-1) 4.9.2

历史背景

首先是Go-Gicro的架构,老教程都是所谓micro/v1或者v2的api,现在(2021)已经被弃用了,micro公司主推v3版本,也就是micro/micro又叫m3o,参考。老的go-micro库被移动至了公司CEO个人git库下面了,现在叫asim/go-micro。

但是我们仍然可以使用go get github.com/micro/go-micro,他会自动重定向至新库。

就像这样:

1
2
3
4
5
6
PS D:\Go\src\micro> go get github.com/asim/go-micro
go: downloading github.com/asim/go-micro v1.18.0
go get: github.com/asim/go-micro@v0.23.0 updating to
github.com/asim/go-micro@v1.18.0: parsing go.mod:
module declares its path as: github.com/micro/go-micro
but was required as: github.com/asim/go-micro

开工

好了,现在源码已经get到了,写个helloword吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"github.com/micro/go-micro/web"
"net/http"
)
func main() {
service := web.NewService(web.Address(":8001"))
service.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("helloword"))
})
service.Run()
}

ETCD给我们的第一个惊喜

直接点goland提供给我们的运行

报:

1
2
3
4
5
6
7
# github.com/coreos/etcd/clientv3/balancer/picker
C:\Users\lms\go\pkg\mod\github.com\coreos\etcd@v3.3.17+incompatible\clientv3\balancer\picker\err.go:37:44: undefined: balancer.PickOptions
C:\Users\lms\go\pkg\mod\github.com\coreos\etcd@v3.3.17+incompatible\clientv3\balancer\picker\roundrobin_balanced.go:55:54: undefined: balancer.PickOptions
# github.com/coreos/etcd/clientv3/balancer/resolver/endpoint
C:\Users\lms\go\pkg\mod\github.com\coreos\etcd@v3.3.17+incompatible\clientv3\balancer\resolver\endpoint\endpoint.go:114:78: undefined: resolver.BuildOption
C:\Users\lms\go\pkg\mod\github.com\coreos\etcd@v3.3.17+incompatible\clientv3\balancer\resolver\endpoint\endpoint.go:182:31: undefined: resolver.ResolveNowOption

好吧,查了之后是etcd使用了老版本的grpc,但依赖中指定的是latest,所以我们要手指一下依赖版本:

在项目的go.mod底部replace中追加一行,如:

1
2
3
replace (
google.golang.org/grpc => google.golang.org/grpc v1.26.0
)

go版本给我们的第二个惊喜

现在我们同步一下依赖关系,点运行。

报:

1
2
3
4
5
panic: qtls.ConnectionState not compatible with tls.ConnectionState

goroutine 1 [running]:
github.com/lucas-clemente/quic-go/internal/handshake.init.1()
C:/Users/lms/go/pkg/mod/github.com/lucas-clemente/quic-go@v0.13.1/internal/handshake/unsafe.go:17 +0x139

好吧,搜过之后发现给了俩解决方案

  • 降到go1.15之下
  • 升级至micro/v3

那我们跟课肯定没办法升级micro了,所以只能选择降级go版本,人懒了,直接在goland里新开了个版本号文件->设置->Go->GOROOT中右侧点加号选下载选择go1.14.15,新建个目录丢进去,等进度条跑完,然后点编译。

第一阶段结束

终于成功了:

1
2021-09-21 22:11:53.796487 I | Listening on [::]:8001

长舒一口气~


使用micro工具创建工程

micro new -type=srv microsrv

注意:名称中不能有下划线,不能以_test结尾,否则会被认为是测试包。

Protobuf 环境

然后我们使用micro new --type="srv" microsrv创建一个micro服务,并生成proto源码:

1
2
3
4
5
6
7
8
9
10
PS D:\Go\src\microsrv> protoc --proto_path=. --go_out=. --micro_out=. proto/microsrv/microsrv.proto
protoc-gen-go: unable to determine Go import path for "proto/microsrv/microsrv.proto"

Please specify either:
a "go_package" option in the .proto source file, or
a "M" argument on the command line.

See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.

--go_out: protoc-gen-go: Plugin failed with status code 1.

查过之后是protoc-gen-go的版本在1.4有了重大更新,改了一堆东西,所以go get指定1.3.5版本再下一次就好了。

go get github.com/golang/protobuf/protoc-gen-go@v1.3.5

编译带consul的main.go

在micro生成的项目中的main.go中,import内添加一行_ "github.com/micro/go-plugins/registry/consul"然后在工程目录中运行 go run main.go --registry=consul或者修改Goland的运行配置中的程序参数也可得到同样的结果。

这样微服务启动时就会自动寻找localhost的consul进行注册了。

1
2
3
4
5
6
2021-09-26 15:52:21.193086 I | Transport [http] Listening on [::]:15501
2021-09-26 15:52:21.193086 I | Broker [http] Connected to [::]:15502
2021-09-26 15:52:21.207387 I | Registry [consul] Registering node: go.micro.srv.microsrv-5d83e247-5e82-4131-af24-3435cdced10c
2021-09-26 15:52:21.257853 I | Subscribing go.micro.srv.microsrv-5d83e247-5e82-4131-af24-3435cdced10c to topic: go.micro.srv.microsrv
2021-09-26 15:52:21.272649 I | Subscribing go.micro.srv.microsrv-5d83e247-5e82-4131-af24-3435cdced10c to topic: go.micro.srv.microsrv

使用micro启动微服务

微服务独立编译运行功能并不完整,只有单个服务再跑。而且没有负载均衡和服务发现。因此需要使用micro server命令启动基础环境。记得确认服务发现的方式。

然后访问localhost:8082,单击下面发现的web服务,即可通过网关负载均衡后访问到微服务,不需要关心微服务具体启动端口。

也可以直接带微服务名成最后一个段,作为路径访问即可。

如:go.micro.web.microweb

则可以直接写为localhost:8082/microweb/

如果需要更改go.micro.web,则需要在micro server启动时指定域名称。

完善生成的micro-web项目

因为web前端要向后端发送以protobuf编码的消息体,所以web项目要指定srv包中已经生成的protoc包依赖。

在microweb/handler/handler.go中,将import的最后一行microweb "path/to/service/proto/microweb"修改为含有protoc包路径。如:microweb "microsrv/proto/microsrv"

同时在项目go.mod中新增两行:

1
2
require microsrv v0.0.0
replace microsrv => ../microsrv

然后回到handler.go中,将报错的microweb.NewMicrowebService方法修改为microweb.NewMicrosrvService,方法name参数修改为microsrv注册的name。这样web服务就能自动拿到srv服务的端口并发送消息了。

不要忘记在main函数中添加consul支持,并在启动时添加–registry=consul参数。

即可在consul中观察到两个服务已经注册了。

升级项目,让项目使用默认的mdns注册中心

删掉每个微服务main.go中import的consul库,去掉运行时的–registry参数即可。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!