在现在云原生技能的大环境下,rpc服务作为最重要的互联网技能,蓬勃发展,诞生了许多知名基于rpc协议的结构,其中就有本文的主角gRPC技能。

一款高性能、开源的通用rpc结构
作者作为一名在JD实习的Cpper,经过一段时刻的学习和实践,发现了C 与Java之间的种种不同,这也让我产生了一个主意:既然rpc需求做到的便是客户端无感知调用,那么客户端和服务端运用的言语也不应该成为束缚,正巧在来JD实习之前,我就有接触过gRPC,所以就想写一篇文章剖析一下gRPC与当今干流rpc结构之间的差异与优势。
对比
1. gRPC的完成原理
在 gRPC 里客户端运用能够像调用本地对象一样直接调用另一台不同的机器上服务端运用的办法,使得运用者能够更容易地创立分布式运用和服务。与许多 RPC 系统相似,gRPC 也是基于以下理念:界说一个服务,指定其能够被远程调用的办法(包含参数和返回类型)。在服务端完成这个接口,并运转一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的办法。
gRPC的客户端和服务端能够用在多样化的环境中运转,运用者能够运用各种官方支撑的言语来构建自己的运用。例如:你能够很容易的运用Java作为gRPC的服务端,而在客户端运用Ruby、Go、Python等言语。

gRPC调用图
2. gRPC的优势与下风
2.1 优势:
2.1.1 多言语支撑
gRPC官方就支撑多种编程言语,包括C#/.NET, C , Dart, Go, Java, Kotlin, Node.js, Objective-C, PHP, Python, Ruby等。开发人员无需考虑运用何种开发言语,能够充分利用言语的优势:C 的内存操作,go言语的灵活,Java的生态丰厚……
2.1.2 基于Protocol Buffers
gRPC默认运用Protocol Buffers作为其接口界说言语(IDL)和底层音讯交换格局。Protocol Buffers是一种言语平和台中立的接口描绘言语,答应开发者界说数据结构和服务接口,并且能够生成多种言语的代码。这使得在不同言语之间完成数据和服务接口的一致性变得简略。其音讯格局采用二进制办法传输,比传统的Json体积更小。
详细的语法界说如下:
- 音讯界说:在 .proto 文件中界说音讯,音讯由字段组成。字段有三种类型:required、optional、repeated,分别表示有必要、可选和重复。
message Person {
required string name = 1;
optional int32 id = 2;
repeated string email = 3;
}
- 枚举界说:枚举类型答应你界说一组有限的可能的值。
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
- 服务界说:服务答应你界说一组相互相关的RPC(远程过程调用)。
service HelloService { rpc SayHello (HelloRequest) returns (HelloReply) {} }
4.字段编号:每个字段都有一个唯一的数字编号。这是必要的,由于在解析过程中,咱们需求知道每个字段的次序。在 .proto 文件中界说的每个字段都有默认值。例如,int32 类型的字段默认值为 0。
5.字段类型:每个字段都有一个类型。例如,string、int32、message 等。对于 message 类型的字段,你需求在括号内界说该音讯的类型。对于 repeated 类型的字段,你能够将多个值放入一个列表中。例如,Person 音讯中的 email 字段能够包含一个电子邮件地址列表。
6.服务调用:在客户端代码中,你能够运用生成的 stub 类来调用服务办法。例如,你能够这样调用 SayHello 办法:
HelloService.stub stub = HelloServiceGrpc.newBlockingStub(channel);
HelloReply response = stub.sayHello(HelloRequest.newBuilder().build());
2.1.3 跨渠道兼容性
gRPC支撑多种软件和硬件渠道。这种跨渠道才能意味着gRPC不仅能在不同的操作系统上运转,还能在各种环境中有用运转,如服务器、移动设备和Web环境。
2.1.4 底层调用协议
gRPC运用HTTP/2作为底层传输协议克服了一些HTTP/1.1版别的一些限制。二进制组帧和紧缩。 HTTP/2 协议在发送和接纳方面均紧凑且高效。在单个 TCP 连接上多路复用多个 HTTP/2 调用。 多路复用可消除队头阻塞。
2.1.5 强壮的社区和生态系统
gRPC的社区和生态系统供给了丰厚的文档、教程和API参考,帮助开发者在不同的言语平和台上运用gRPC。这种广泛的社区支撑也促进了对新言语平和台的支撑。例如:Dubbo3对gRPC的支撑、gRPC-Swift、gRPC-Spring。

github上的gRPC生态支撑
2.1.6 严格标准
具有 JSON 的 HTTP API 没有正式标准。 开发人员为 URL、HTTP 谓词和响应代码的最佳格局争辩不休。gRPC 标准对 gRPC 服务有必要遵从的格局进行了规则。 gRPC 消除了争辩并为开发人员节省了时刻,由于 gRPC 在各个渠道和完成中都是一致的。
2.2 下风:
2.2.1 浏览器支撑有限
当下,不可能直接从浏览器调用gRPC服务。gRPC很多运用HTTP/2功能,没有浏览器供给支撑gRPC客户机的Web恳求所需的操控等级。例如,浏览器不答应调用者要求运用的HTTP/2,或许供给对底层HTTP/2结构的拜访。
2.2.2 不是人类可读的
HTTP API恳求以文本方式发送,能够由人读取和创立。默认情况下,gRPC音讯运用protobuf编码。**虽然protobuf的发送和接纳功率很高,但它的二进制格局是不可读的8。protobuf需求在.proto文件中指定的音讯接口描绘才能正确反序列化。需求额外的工具来剖析线路上的Protobuf有用负载,并手艺编写恳求。

grpc与传统rpc相比较
- demo展现
下面作者将运用C 与go作为开发言语来展现gRPC强壮的跨言语调用才能
项目结构:
grpc-demo
├── cpp
│ ├── CMakeLists.txt // C 的CMakeLists.txt文件,用来生成makefile
│ ├── cmake // 用来存放一些cmake函数
│ │ └── common.cmake // cmake函数
│ ├── include // 头文件
│ ├── proto // Protocol Buffers界说文件
│ │ └── helloworld.proto
│ └── src // C 源文件
│ └── main.cpp
├── go
│ ├── Makefile // makefile脚本
│ ├── go.mod // Go言语包管理
│ ├── proto
│ │ ├── helloworld.proto
│ ├── service
│ └── src // go源文件
│ └── main
│ └── main.go
└── proto
└── helloworld.proto
项目源代码:github.com/Constantine…
总结
回归标题,gRPC由于他强壮的可扩展性,轻便的底层传输格局,越来越多的企业在技能选型时选择了它,我也希望未来能有一款运用能够经过gRPC发挥出每种言语的优势,绽放出绚丽的颜色。