ProtoBuf 与 gRPC (2)

ProtoBuf 与 gRPC

这个数字可是有大用处的,这里我们是写着连续的,但是事实上他们可以是不连续的,那么它们的用处是啥?根据官方文档的介绍,在序列化 ProtoBuf 的时候,它们也是以 Key-Value 的形式压缩的,但是,它们的 key 不是这里面的字面量,而是后面的数值,也就是说对于 "query" 这个字段,我们保存的不是 "query" 的字符串,而是 1 这个数字,这样就将我们的压缩量降低了一大截。

除此之外,对于 value 的处理也是有特别处理的,这里有点类似于 UTF 的处理方式,存在一种称为 varint 的类型,如果是 0-127 的数字,那么我们可以直接用 1 个字节(最多用了 7 位)表示,如果不够用了,要表示 128,那么分为两个字节,不同之处在于,低位的字节要取反码保存,就拿 128 来说吧:

ProtoBuf 与 gRPC

这里有意思的地方在于 2 和 3 行,在第 2 行,我们可以看到是对低位的字节取反码,然后在第 3 行,是将高低位转化,最终成为了第 4 行中的表示。这里我有个疑惑就是,为啥要这么操作,文档中的说明是这样可以从左到右搜索字节,如果第一位为 1 则表示这个字节后面还有字节,那么如果我对高位进行取反的话也能得到同样的效果啊。

我认为,这里除了最高位是 1 表示还存在后续字节之外,将高低字节调转在解析的时候会方便不少,因为我们可以看到,字节流从左到右进行解析,最先解析的字节应该是最低位的,也就是说如果我们算 128 的话,最先解析的结果是 127 ,然后是 1,加起来就是 128 了。当然,这对于在程序语言中单类型可以表示完全的好像没什么优势,但是如果并不能表示完全的就有意义了,例如让一种不支持 64 位长整数的程序语言处理 uint64 的数值。

gRPC

ProtoBuf 除了经常被用于数据保存交换之外,还被用于定义 gRPC 服务,gRPC 也是 G 家公开的高性能 RPC 调用框架,号称高效,支持广(题外话,似乎度娘也开源了一款不错的 RPC 框架)。

使用 gRPC 的步骤其实还是很简单的,因为我们只需要做简单几步,就将整体的代码结构创建好了,剩下的工作都是填业务了。无论怎样,第一步肯定还是先明确一下接口的详情:

ProtoBuf 与 gRPC

要定义一个接口,除了定义函数原型之外,还需要定义参数和返回值,gRPC 也一样,这里定义接口的形式和 Go 语言有点类似,语法为:

rpc 函数名 (参数) returns (返回值) {}

参数 和 返回值 都是我们在前面已经很熟悉的 Message 定义。有了这些定义之后,我们可以很简单得通过刚才的方式生成框架代码:

$ protoc proto/service.proto --go_out=plugins=grpc:service

随后我们就可以在 service 目录下发现生成的 Go 语言代码,然后我们看到文件:service/proto/service.pb.go,会发现已经生成了我们的函数:

ProtoBuf 与 gRPC

重新根据我们自己的逻辑编辑它即可,但是这仅仅只是一个实现,并不能直接对外提供服务,所以我们还需要编写一段服务器的代码,用来驱动这个 service:

ProtoBuf 与 gRPC

然后运行看看:

$ go run main.go

这就是如何搭配 ProtoBuf 和 gRPC 的一个方式。

Reference

Golang Protobuf

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxgsp.html