go-micro框架的QuickStart

go-micro是基于grpc的一个框架,一样也是用protobuf进行序列化,主要设计哲学是“可插拔”,主要是用于分布式系统开发。至于为什么用go-micro,主要是它对grpc封装的很好,让我们可以更便利。
下面是它的架构图
go-micro框架的QuickStart
文章图片

【go-micro框架的QuickStart】同样的一开始也是要编写.proto 文件
hello.proto文件

syntax = "proto3"; //指定语法版本 package helloword; //指定生成后的 hello.pb.go 的包名//一个 RPC 服务通过参数和返回类型来指定可以远程调用的方法 service Hello { // rpc 定义可远程调用服务 rpc HelloWorld (HelloRequest) returns (HelloReply) {} }//消息定义的关键字,相当于struct message HelloRequest { // [修饰符] 类型 字段名 = 标识符; //标识符是用来在二进制格式中识别各个字段的,可以简单理解为序列化后的二进制数据中的布局位置顺序 string name = 1; }message HelloReply { string message = 1; }

和上一篇博客写的hello.proto没有任何变化,因为两者都是用protobuf
接下来在终端键入protoc -I . --micro_out=. --go_out=. ./hello.proto
go-micro框架的QuickStart
文章图片

关于这条命令,在上一篇的博客中介绍过了,这里就不多说了,唯一不同的就是这里多了一个--micro_out参数,这个参数其实和--go_out没有什么大的区别,是指定编译.proto文件后生成的.micro.go文件的路径
可以看到在当前路径下会生成两个文件,与grpc不同,go-micro会多生成一个.micro.go文件,这个就是go-micro的接口文件
go-micro框架的QuickStart
文章图片

下面就是实现服务端和客户端了
go-micro框架的QuickStart
文章图片

服务端的实现
package main import ( micro "github.com/micro/go-micro" proto "helloworld" "log" "context" )//用于实现HelloServer type server struct{}//服务实现 func (s *server) HelloWorld(ctx context.Context, req *proto.HelloRequest, rsp *proto.HelloReply) (error) { log.Printf("Received: %v", req.Name) rsp.Message = "Hello " + req.Name return nil }func main() { // 创建服务 service := micro.NewService( micro.Name("helloworld"), ) // 初始化 service.Init() // 注册handler proto.RegisterHelloHandler(service.Server(), new(server)) // 运行 if err := service.Run(); err != nil { log.Println(err) }}

和纯grpc实现的代码有点不一样,func (s *server) HelloWorld这个方法的参数和返回值和grpc实现的不一样了,在main()中也不用自己来监听端口,由go-micro底层帮你实现了
服务端主要有4个工作:
①实现在.proto 文件中定义的方法接口
②初始化服务
③注册handler
④运行
客户端的实现
package mainimport ( micro "github.com/micro/go-micro" proto "helloworld" "log" "context" "os" )func main() { // 创建服务 service := micro.NewService(micro.Name("helloworld")) service.Init() // 创建客户端 hello := proto.NewHelloService("helloworld", service.Client()) name := "World" //获取命令行参数 if len(os.Args) > 1 { name = os.Args[1] } // 唤起服务 rsp, err := hello.HelloWorld(context.TODO(), &proto.HelloRequest{Name: name}) if err != nil { log.Println(err) } // 响应 log.Println(rsp.Message) }

和grpc实现的客户端基本一致,没有什么非常大的改动
运行
go run server/main.go
go-micro框架的QuickStart
文章图片

这个节点就是我们在服务端里设置的micro.Name(),这个节点名还是很重要的,关乎我们的客户端能否找到它
go run client/main.go
go-micro框架的QuickStart
文章图片

注意
go-micro框架的QuickStart
文章图片

在客户端实现的第17行,第一个参数是指定客户端所要找寻服务端的节点名,因此这个节点名一定要和服务端的保持一致,否则运行时就会报错说找不到节点。
比如说只将客户端实现的第17行改为
hello := proto.NewHelloService("hello", service.Client())

运行后,就会报错说找不到节点,就是因为客户端要找的节点在服务端中找不到,这是因为在这整个案例中,我们在服务端中只定义了一个节点helloworld,而修改后的客户端要找的节点hello在服务端中没找到,两个节点名都不一致自然就找不到了,自然就报错了
go-micro框架的QuickStart
文章图片

参考
go-micro官方文档

    推荐阅读