和美大家说 | 微服务gRPC使用浅聊
什么是RPC?
RPC是Remote Procedure Call的缩写形式,即远程过程调用。程序的调用一般有进程内调用、进程间调用、本地过程调用和远程过程调用。今天我们主要说的是远程过程调用(RPC),程序能利用其它程序或计算机处理的进程。客户机/服务器模式计算把远程过程调用与其它技术(如消息传递)一道,作为系统间通信的一种机制。客户机执行自己的任务,但靠服务器提供后端文件服务,RPC为客户机提供向后端服务器申请服务的通信机制。
RPC优点:
1、提高开发效率,开发人员可以把更多精力放在具体的接口实现,而不必考虑数据的底层传输问题。
2、大多数RPC框架都是很多优秀开发人员的智慧结晶,它们的功能实现和执行效率都很优秀。
3、client端和server端必须遵循统一的接口规范,避免产生client和server之间接口或数据局结构不匹配的情况。
什么是gRPC?
gRPC由Google开发的一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP2 设计。该框架提供了负载均衡,跟踪,智能监控,身份验证等功能,可以实现系统间的高效连接。另外,在分布式系统中,gRPC框架也有有广泛应用,实现移动社会,浏览器等和服务器的连接。目前提供的有C、Java和Go语言版本,分别是:grpc、grpc-java、grpc-go其中C版本支持C、C++,Node.js、Python、Ruby、PHP和C#支持,gRPC的核心是一个Protobuf。
什么是Protobuf?
Protobuf是一个轻便高效的结构数化数据存储格式,可以用于结构化数据序列化。Protobuf使用的是varints压缩算法编码。在varint中,除了最后一个字节之外的每个字节中都包含一个msb(most significant bit)设置(使用最高位),这意味着其后的字节是否和当前字节一起来表示同一个整型数值。即在varints编码的二进制字节中,没有固定长度的字节空间,避免固定长度的编码位置的空间浪费。所以在数据传输和存储方面,protobuf效率优于json、xml等。原理如图:
比较可见相比于json和xml,protobuf对象序列化时可以节省非常大的空间,从而带来非常快的传输速度,另外由于protobuf表示简单,解析速度也更快。
protobuf有什么用?
Xml、Json是目前常用的数据交换格式,它们直接使用字段名称维护序列化后类实例中字段与数据之间的映射关系,一般用字符串的形式保存在序列化后的字节流中。消息和消息的定义相对独立,可读性较好。但序列化后的数据字节很大,序列化和反序列化的时间较长,数据传输效率不高。
Protobuf和Xml、Json序列化的方式不同,采用了二进制字节的序列化方式,用字段索引和字段类型通过算法计算得到字段之前的关系映射,从而达到更高的时间效率和空间效率,特别适合对数据大小和传输速率比较敏感的场合使用。
Protobuf通过将结构化的数据进行串行化(序列化),从而实现数据存储 / RPC 数据交换的功能
1. 序列化:将数据结构或对象转换成二进制串的过程;
2. 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。
Protobuf优点:
更小——序列化后,数据大小可缩小约3倍;
更快——序列化速度更快,比xml和JSON快20-100倍,体积缩小后,传输时,带宽也会优化;
更简单——proto编译器,自动进行序列化和反序列化;
维护成本低——跨平台、跨语言,多平台仅需要维护一套对象协议(.proto);
可扩展——“向后”兼容性好,不必破坏已部署的、依靠“老”数据格式的程序就可以对数据结构进行升级;
加密性好——HTTP传输内容抓包只能看到字节,在传输数据量大、网络环境不稳定的数据存储和RPC数据交换场景比较合适。
gRPC主要原理图
gRPC依赖场景及解决方案
gRPC主要使用protobuf对数据进行序列化存储、传输及反序列化。在这个过程中,客户端和服务端的序列化提前编写完成序列化规则文件proto文件。并且使用不同版本的protobuf编译器生成对应语言的API。
Python编译:
python-m grpc_tools.protoc -I=protos --python_out=./rpc_package --grpc_python_out=./rpc_package ./protos/cal.proto
结果如下
API接入服务端或者客户端
在微服务集群中,为了方便每个客户端及服务端都能灵活调用。可以采用将gRPC代码pip化安装。保证客户端和服务端序列化规则一致。
然后固定的客户端序列化参数和反序列化返回。
反序列化可以提供dict和json两种格式。
gRPC优缺势
gRPC采用map对象,擅长处理大对象。对象内容越大,效率越高。甚至能达到http的百倍。对象个体多且小的情况下传输效率并无明显优于http,甚至略差。Protobuf不支持多维数组。如处理多维数组,需要自行封装对象装换,会降低微服务调用效率。