了解下 Protobuf 相关概念
9月 22, 2020
说 Protobuf 之前,要先知道 RPC 是什么,可以说 Protobuf 是实现 RPC 的接口描述语言。
RPC #
RPC,全称 Remote Procedure Call,中文叫远程过程调用。
go 语言基于标准库实现了一套自己的 RPC 调用规则:方法只能有两个可序列化的参数,其中第二个参数是指针类型,并且返回一个error类型,同时必须是公开的方法1。
Only methods that satisfy these criteria will be made available for remote access; other methods will be ignored:
- the method's type is exported.
- the method is exported.
- the method has two arguments, both exported (or builtin) types.
- the method's second argument is a pointer.
- the method has return type error.
In effect, the method must look schematically like
func (t *T) MethodName(argType T1, replyType *T2) error
举个例子 #
定义函数
type HelloService struct {
}
func (h *HelloService) SayHello(s string, sp *string) error {
fmt.Println("hello func", s, sp)
return nil
}
server.go
func main() {
rpc.RegisterName("HelloService", new(proto.HelloService))
listener, err := net.Listen("tcp", ":6666")
if err != nil {
panic(err)
}
conn, err := listener.Accept()
if err != nil {
panic(err)
}
rpc.ServeConn(conn)
}
client.go
func main() {
client, err := rpc.Dial("tcp", "localhost:6666")
if err != nil {
log.Fatal("dialing:", err)
}
var reply string
err = client.Call("HelloService.SayHello", "param", &reply)
if err != nil {
log.Fatal(err)
}
fmt.Println(reply) //hello func param 0xc00009d390
}
这样在 go 语言内部也可以直接使用 RPC 调用了。但是也就仅限于 go 语言的项目之间的通信,如果要跨语言,还需要一套标准的描述语言来定义自己有什么方法供别人使用,那就有请 Protobuf。
Protobuf #
Protobuf 作为接口规范的描述语言,可以作为设计安全的跨语言 RPC 接口的基础工具。
举个例子 #
定义函数
type HelloService struct {
}
func (h *HelloService) SayHello(s string, sp *string) error {
fmt.Println("hello func", s, sp)
return nil
}
编写 protobuf 文件
syntax = "proto3";
package proto;
service HelloService {
rpc SayHello(HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
string name_pointer = 2;
}
message HelloResponse {
}
生成 hello.pb.go 文件
protoc --go_out=. proto/hello.proto
# 如果使用 gRPC 框架
protoc --go_out=plugins=grpc:. proto/hello.proto
Protobuf 进阶语法 #
gRPC #
gRPC是基于HTTP/2 协议、使用 Protobuf 作为接口描述语言的一套完整的 RPC 远程调用框架。使用 gRPC 框架定义 Server和 Client 代码可以参考官方 Helloworld 。
net/rpc 标准库文档 https://golang.org/pkg/net/rpc/ ↩︎
Protobuf 3 语法指南 https://colobu.com/2017/03/16/Protobuf3-language-guide/ ↩︎
Protobuf 官方文档 https://developers.google.com/protocol-buffers/docs/overview ↩︎