gRPC
简介
gRPC:A high-performance, open-source universal RPC framework
gRPC客户端和服务端可以在多种环境中运行和交互;例如服务端使用Java写;可以用Go语言写客户端调用
gRPC与Protobuf介绍
- 微服务架构中每个服务对应的代码库都是独立运行的;gRPC 可以实现微服务,将大的项目拆分为多个小且独立的业务模块;即服务;各服务之间使用高效的protobuf协议进行RPC调用
- 可以使用proto files 创建gRPC服务;使用message类型来定义方法参数和返回类型
- Protobuf实际是一套类似Json或者XML的数据传输格式和规范,用于不同应用或进程之间进行通信时使用。通信时所传递的信息是通过Protobuf定义的message数据结构进行打包,然后编译成二进制的码流再进行传输或者存储。
Protobuf的优点
-
足够简单
-
序列化后体积很小:消息大小只需要XML的1/10 ~ 1/3
-
解析速度快:解析速度比XML快20 ~ 100倍
-
多语言支持
-
更好的兼容性,Protobuf设计的一个原则就是要能够很好的支持向下或向上兼容
Protobuf语法
-
基本规范
- 文件以.proto作为文件后缀;除结构定义外的语句以分号结尾
- 结构定义包含:message、service、enum
- rpc方法定义后面的分号可有可无
- Message命名采用驼峰法;字段命令使用小写字母加下划线
- Enum命名采用驼峰法;字段命令使用大写字母加下划线
- Service 和rpc方法名统一采用驼峰法
-
字段规范
-
字段格式:限定修饰符|数据类型|字段名称|=|字段编码值|[字段默认值]
-
限定修饰符包括:
- repeated:表示该字段可以包含 0~N 个元素。其特性和 optional 一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值
- optional:标识可选字段;可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。—因为 optional 字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为 optional 字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡
- required:必须字段;对于发送方,在发送消息前必须设置该字段的值;对于接受方,在必须能够识别该字段的意思;两种情况的非状态都会造成编译异常;导致消息丢失
-
字段编码值:
- 有了该值,通信双方才能互相识别对方的字段,相同的编码值,其限定修饰符和数据类型必须相同,编码值的取值范围为 1~2^32(4294967296)
- 其中 1~15 的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低,所以建议把经常要传递的值把其字段编码设置为 1-15 之间的值
- 1900~2000 编码值为 Google protobuf 系统内部保留值,建议不要在自己的项目中使用
-
使用gRPC protobuf生成工具生成.go文件
protoc -I . --go_out=plugins=grpc:. ./user.proto
使用go-micro生成.go文件
protoc -I . --micro_out=. --go_out=. ./user.proto
关于protobuf生成工具生成.go文件中的结构体自定义标记
源代码网址:http://www.github.com/favadi/protoc-go-inject-tag
用法
// file: test.proto
syntax = "proto3";
package pb;
message IP {
// @inject_tag: valid:"ip",json:"address"
string Address = 1;
}
//生成:
type IP struct {
// @inject_tag: valid:"ip"
Address string `protobuf:"bytes,1,opt,name=Address,json=address" json:"address" valid:"ip"`
}
命令行使用:
-
protoc --go_out=. test.proto //表示在当前文件下生成.go文件
-
protoc-go-inject-tag -input=./test.pb.go //对文件test.pb.go 的tag进行修改