go-micro框架的QuickStart

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

同样的一开始也是要编写.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
在这里插入图片描述
关于这条命令,在上一篇的博客中介绍过了,这里就不多说了,唯一不同的就是这里多了一个--micro_out参数,这个参数其实和--go_out没有什么大的区别,是指定编译.proto文件后生成的.micro.go文件的路径

可以看到在当前路径下会生成两个文件,与grpc不同,go-micro会多生成一个.micro.go文件,这个就是go-micro的接口文件
在这里插入图片描述

下面就是实现服务端和客户端了
go-micro框架的QuickStart_第2张图片

服务端的实现

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 main

import (
	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_第3张图片
这个节点就是我们在服务端里设置的micro.Name(),这个节点名还是很重要的,关乎我们的客户端能否找到它

go run client/main.go
在这里插入图片描述

注意

在这里插入图片描述
在客户端实现的第17行,第一个参数是指定客户端所要找寻服务端的节点名,因此这个节点名一定要和服务端的保持一致,否则运行时就会报错说找不到节点。

比如说只将客户端实现的第17行改为

hello := proto.NewHelloService("hello", service.Client())

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

参考
go-micro官方文档

你可能感兴趣的:(框架)