gRPC
什么是RPC
RPC指的是远程过程调用(Remote Procedure Call),能在本地调用其他服务器上的函数,它的调用包含了传输协议和编码协议等,而开发人员无需额外地为这个过程进行编码。
什么是gRPC
gRPC是一个高性能、开源和通用的RPC框架,面向移动和基于HTTP/2设计,并且提供了多种语言的支持。
gRPC基于HTTP/2标准设计,有着如双向流、流控、头部压缩、单TCP连接上的多路复用请求等特性。这些特性使得其在移动设备上表现更好,在一定的情况下更节省空间占用。
gRPC的接口描述语言IDL(Interface description language)使用的是protubuf,都是由google开源的。
gRPC调用模型

- 客户端(gRPC Stub)在程序中调用某方法,发起RPC调用
- 对请求信息使用protobuf进行对象序列化压缩(IDL)
- 服务端(gRPC Server)接收到请求后,解码请求体,进行业务逻辑处理并返回
- 对响应结果使用protobuf进行对象序列化压缩(IDL)
- 客户端接收到服务端响应,解码请求体。回调被调用的A方法,唤醒正在等待响应(阻塞)的客户端调用并返回响应结果。
Protobuf
什么是Protbuf
Protobuf Buffers(Protobuf)是一种与语言、平台无关,可扩展的序列化结构数据的数据描述语言。常用于通信协议,数据存储等,相较于JSON、XML、它更小,更快。
基本语法
1 | syntax = "proto3"; |
- 首先需要声明使用的语法版本,不声明的话默认使用的是proto2。目前主流使用的为proto3
- 定义名为
Greeter
的RPC服务(Service),其包含RPC方法SayHello
,入参为HelloRequest
消息体,出参为HelloReply
消息体 - 定义
HelloRequest
、HelloReply
消息体,每一个消息体的字段包含三个属性:类型、字段名称、字段编号。在消息体的定义上,除类型以外均不可重复。
在编写完proto文件后,一般会进行编译和生成对应语言的proto文件操作,这个时候Protobuf的编译器会根据选择的语言不同,调用的插件情况,生成相应语言的Service Interface Code和Stubs。
基本数据类型
Proto Type | C++ Type | Java Type | Go Type | PHP Type |
---|---|---|---|---|
double | double | double | float64 | float |
float | float | float | float32 | float |
int32 | int32 | int | int32 | integer |
int64 | int64 | long | int64 | integer/string |
uint32 | uint32 | int | uint32 | integer |
uint64 | uint64 | long | uint64 | integer/string |
sint32 | int32 | int | int32 | integer |
sint64 | int64 | long | int64 | integer/string |
fixed32 | uint32 | int | uint32 | integer |
fixed64 | uint64 | long | uint64 | integer/string |
sfixed32 | int32 | int | int32 | integer |
sfixed64 | int64 | long | int64 | integer/string |
bool | bool | boolean | bool | boolean |
string | string | String | string | string |
bytes | string | ByteString | []byte | string |
什么场景下使用gRPC?
gRPC与RESTful API对比
特性 | gRPC | RESTful API |
---|---|---|
规范 | 必须.proto | 可选OpenAPI |
协议 | HTTP/2 | 任意版本的HTTP协议 |
有效载荷 | Protobuf(小、二进制) | JSON(大、易读) |
浏览器支持 | 否(需要grpc-web) | 是 |
流传输 | 客户端、服务端、双向 | 客户端、服务端 |
代码生成 | 是 | OpenAPI+第三方工具 |
使用场景分析
- 低延时,高可用的分布式系统
- 移动端与云服务端的通讯
- 使用protobuf,独立于语言的协议,支持多语言之间的通讯
- 可以分层扩展,如:身份验证,负载均衡,日志记录,监控等