安装
go-micro
go-micro的repo其实有些混乱,以及除了go-micro之外,还有一个micro的repo,两者之间的关系我暂时还没搞懂(似乎micro可安装后对go-micro进行查看)
安装go-micro的v3版本
go get -u github.com/asim/go-micro/v3
如果出问题记得设置
go env -w GO111MODULE=on
go-micro plugins
go-micro在v1和v2采用go-plugins
的一个单独repo Github,但在v3的时候又重新回到了go-micro/plugins
下面Github
v3
go get -u github.com/asim/go-micro/plugins/registry/consul/v3
安装 Protobuf 相关工具
接下来,安装基于 Protobuf 格式服务声明文件自动生成微服务原型代码所需要的一些工具。
安装 protoc-gen-micro
首先是 protoc-gen-micro
,该工具适用于在 Micro 框架中基于 Protobuf 文件生成服务代码,在项目根目录下运行如下 go get
命令安装:
go get github.com/micro/micro/v3/cmd/protoc-gen-micro@master
// 到 protoc-gen-micro 根目录下安装,bin 文件会到 $GoPath:\bin\
go install .
// 把 $GoPath:\bin\ 添加到系统环境变量的 Path
安装protobuf
protobuf介绍自行搜索,类似json但占用更小的空间 在官方Github里的release下载最新的包,选择对应的os,比如我下载的是protoc-3.14.0-win64.zip
(不懂为什么一群人教程下32位)
放到想要的安装目录下,D:\repository\protoc-22.0-rc-3-win64\bin
,把bin目录加入环境变量
命令行
>protoc --version
libprotoc 22.0-rc3
安装protoc-gen-go
protobuf默认是不支持go的编译的,因此需要安装protoc-gen-go
来支持编译为go文件
go get google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
// 到 protoc-gen-go 根目录下安装,bin 文件会到 $GoPath:\bin\
go install .
consul
这里下了一个docker镜像包,因为本身也准备用docker,安装在电脑上似乎没那么必要
docker pull consul
docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul agent -server -bootstrap-expect=1 -ui -bind=0.0.0.0 -client=0.0.0.0
浏览器localhost:8500
,可以看到当前已注册的服务
测试服务
至此,我们已经做好了所有外围的准备工作,接下来,可以正式通过 Go Micro 框架编写第一个微服务接口了。
服务接口声明
在项目的根目录下新建一个 proto
子目录,然后在 proto
目录下创建一个 Protobuf 格式的服务接口声明文件 greeter.proto
:
syntax = "proto3";
package proto;
option go_package = "/proto";
service Greeter {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string greeting = 1;
}
如上述代码所示,我们定义了一个名为 Greeter
的服务
通过服务声明生成原型代码
接下来,我们就可以借助前面安装的 protoc
工具通过服务声明文件生成相应的服务原型代码(在项目根目录下运行
):
protoc --micro_out=. --go_out=. proto/greeter.proto
HelloWorld微服务
这里我们创建一个service和一个client,模拟最简单的微服务的交互场景(代码改编于go-micro/example/service)
目录结构
文件夹go-micro-test
│ client.go
│ go.mod
│ go.sum
│ greeter.go
│
└─proto
greeter.pb.go
greeter.pb.micro.go
greeter.proto
定义proto
如果采用GoLand开发的话推荐安装插件Protocol Buffer Editor
,网上看到推荐Protobuf Support
已经被deprecated了
greeter.proto
syntax = "proto3";
package proto;
option go_package = "/proto";
service Greeter {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string greeting = 1;
}
这里定义了一个叫做Greeter
的调用方法(client对service的rpc),其中Request
就是请求的数据内容,Response
就是service返回的内容 package
是生成的文件的包名,go_package
是总的包路径
生成对应go文件:
protoc --micro_out=. --go_out=. proto/greeter.proto
获得greeter.pb.go
和greeter.pb.micro.go
编写service
这里叫做greeter.go
package main
import (
"context"
"github.com/asim/go-micro/plugins/registry/consul/v3"
"github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/registry"
proto "go-micro-test/proto"
"log"
)
type Greeter struct{}
func (g *Greeter) Hello(ctx context.Context, req *proto.Request, rsp *proto.Response) error {
rsp.Greeting = "Hello " + req.Name
return nil
}
func main() {
consulReg := consul.NewRegistry(registry.Addrs(":8500"))
service := micro.NewService(
micro.Name("greeter"),
micro.Registry(consulReg),
)
service.Init()
proto.RegisterGreeterHandler(service.Server(), new(Greeter))
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
这里Greeter
和它的方法Hello
是用来实现我们在proto中定义的调用
编写client
文件client.go
package main
import (
"context"
"fmt"
"github.com/asim/go-micro/plugins/registry/consul/v3"
"github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/registry"
proto "go-micro-test/proto"
)
func main() {
consulReg := consul.NewRegistry(registry.Addrs(":8500"))
service := micro.NewService(
micro.Name("greeter.client"),
micro.Registry(consulReg),
)
service.Init()
greeter := proto.NewGreeterService("greeter", service.Client())
rsp, err := greeter.Hello(context.TODO(), &proto.Request{Name: "World"})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(rsp.Greeting)
}
运行
首先启动ervice
go run greeter.go
其次启动client
go run client.go
如无意外可以看到client这边显示Hello World