Golang-gRPC & Protocol Buffers

之前都是使用RESTful API开发
换工作面试几轮之後发现有蛮多家公司都在使用gRPC
就多学一个技能,顺便做个笔记
希望可以帮助到也是初接触gRPC的你
每个topic的最後会附上参考资料,建议要进去看过一遍

我的开发环境

  • 语言:Go
  • OS:macOS

gRPC是什麽?

全名:gRPC (gRPC Remote Procedure Calls)

是Google发起的一个开源远端程序呼叫 (Remote procedure call) 系统。该系统基於 HTTP/2 协定传输,使用Protocol Buffers 作为介面描述语言。

gRPC 与 RESTful API & JSON 的比较

讲几个gRPC的优点,其他更加详细的内容可以参照Microsoft Docs有更详细的说明

  • 文件即是程序结构,程序内不用另外写object mapping资料

  • 文件透过binary直接转译成程序,支援多种语言

  • 资料会经过protobuf编码,人类无法直接看懂资料,安全性相较於JSON较高(但同时也是缺点,因为人看不懂)

  • 效能透过protobuf序列化後效能较好

  • 参考资料:https://docs.microsoft.com/zh-tw/aspnet/core/grpc/comparison?view=aspnetcore-5.0

Protobuf

proto2 与 proto3的区别

有的人在第一次看到protobuf的时候可能会注意到有proto2 与 proto3
使用上建议proto3
因为支援更多种语言,也有做出许多改进
详细请见参考资料

安装步骤

go get github.com/golang/protobuf/protoc-gen-go
  • 在terminal执行echo $PATH,找到系统路径,把protocprotoc-gen-go丢到系统路径去
    注意:PATH预设可能会被隐藏资料夹,mac要看到隐藏资料夹按command+shift+.
    https://ithelp.ithome.com.tw/upload/images/20210222/20118878MRPbnUpw9K.png

撰写protocol文件,并转译成程序码

撰写protocol文件

详细规格可以看文件,以下是简单tutorial.proto范例

//使用proto3
syntax = "proto3";
//定义所属package
package tutorial;

//定义输出的路径,没有写会出现提示警告讯息,但是目前都是生成在执行的资料夹下
//option go_package = "./tutorial";

//定义API interface
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

//定义资料结构
// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
}

转译成程序码

转化为Go程序的command

protoc --go_out=. *.proto
protoc --go_out=plugins=grpc:. *.proto // 用这个比较好,连grpc的service也会跟着转译

Read & Write,proto doc在文末有附上

// ProtoExample ...
func ProtoExample() {
	// 你一定很好奇这个struct在哪,在tutorial.pb.go
	p := HelloRequest{
		Name: "Alice",
	}

	// Writing a Message
	bp, err := proto.Marshal(&p)
	if err != nil {
		log.Fatal(err)
	}

	// Reading a Message
	var data HelloRequest
	if err = proto.Unmarshal(bp, &data); err != nil {
		log.Fatal(err)
	}
	log.Println(&data)
}

gRPC Server & Client

下载gRPC package

go get -u google.golang.org/grpc

实作API & Server端

type service struct {
	UnimplementedGreeterServer
}

func (s *service) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) {
	log.Printf("Received: %v", in.GetName())
	return &HelloReply{Message: "Hello, " + in.GetName()}, nil
}

// GRPCServer ...
func GRPCServer() {
	addr := "127.0.0.1:8080"
	lis, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	log.Println("Server listening on", addr)
	gRPCServer := grpc.NewServer()
	RegisterGreeterServer(gRPCServer, &service{})
	if err := gRPCServer.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

实作Client端

const (
	address     = "127.0.0.1:8080"
	defaultName = "world"
)

// GPRCClient ...
func GPRCClient() {
	// Set up a connection to the server.
	conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := NewGreeterClient(conn)

	// Contact the server and print out its response.
	name := defaultName
	if len(os.Args) > 1 {
		name = os.Args[1]
	}
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := c.SayHello(ctx, &HelloRequest{Name: name})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
	log.Printf("Greeting: %s", r.GetMessage())
}

参考资料:

Bloomrpc

这是去google搜寻之後看到铁人赛的文章使用的GUI测试工具
专门用来对gRPC做使用

使用方法

  • 按+号import proto file
  • 选择你要测试的message
  • 输入data
  • 输入address
  • 按>号输出之後就能看到结果

bloomrpc github:https://github.com/uw-labs/bloomrpc

总结

参考的资料非常多,细节很多
文件要多看,只能尽量把作法跟参考资料给集中
总结步骤的话可以分成

  • 安装binary(protoc、protoc-gen-go。有的范例还有安装protoc-gen-go-grpc,这里没有使用)
  • 撰写.proto(使用proto3撰写,定义service、message)
  • 使用binary parse to code
  • 实作API、Server、Client

其他相关


<<:  调用 Properties.Resources 全域资源档

>>:  【左京淳的JAVA学习笔记】第五章 class定义与物件生成

Day13:今天来聊一下Microsoft Defender for Endpoint的配置警报和检测

Microsoft Defender for Endpoint 提供警报和检测的配置选项。 配置包括...

Day-3: Rails的Route + MVC架构

MVC模式(Model–view–controller) 是软件工程中的一种软件架构模式, 把软件...

D14: 工程师太师了: 第7.5话

工程师太师了: 第7.5话 杂记: 注解是程序语言中用来解释程序码中的部分,可增加程序的可读性、可维...

[DAY26]Istio延伸功能-External Authorization

External Authorization这功能主要拿来做request的验证,可以在reques...

连续 30 天 玩玩看 ProtoPie - Day 20

突然注意到信件夹出现ProtoPie 寄来的信,分享更多不同的教学。 很好奇他们是怎麽找到这些人,并...