gRPC

gRPC是什么

gRPC是Google开源的基于Protobuf的RPC框架。使用了高性能的Protobuf和HTTP/2。

官方定义gRPC是一种现代的、开源的、高性能的跨平台的RPC框架。 它可以高效的用做服务之间的互联互通,可以在一个数据中心或者跨数据中心的来处理,并且可以以插件形式来支持负载均衡、跟踪、健康检查以及认证等。 另外,他还适用于最后一公里的解决方案,用在分布式计算连接设备,移动端程序和浏览器等连接后端服务等。

gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services.

RPC是什么

RPC是Remote Procedure Call,指的是远程过程调用,允许运行在一台计算机上的程序,像调用本地接口一样,来调用处于另外一台计算机上的程序的接口。 既然是远程,那么一般都不在本地(虽然也可以是在本地),所以调用过程必然包含数据的编码和传输。

RPC框架是什么

RPC理解了,那么RPC框架呢?如果只能完成RPC调用,那仅仅能算一个RPC库。 既然作为框架,那么得解决一系列的问题,作为一个完整的RPC框架, 我认为,至少应该包含服务注册/发现,负载均衡,服务治理等功能,且可以方便的接入流量监控系统。 当然,有一些比较简单的RPC框架,通过组合多个组件,也是能完成这些功能的。

有哪些RPC框架

目前比较主流的RPC框架除了gRPC之外,还有ThriftRpcxDubbo, 和Motan

Thrift是Apache的一个跨语言的高性能的服务框架,得到了比较广泛的应用。 Facebook的大部分服务都是用Thrift在通信,并在其上发展出了FBThrift

Dubbo是Alibaba开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成。 不过,略有遗憾的是,据说在淘宝内部,dubbo由于跟淘宝另一个类似的框架HSF(非开源)有竞争关系, 导致dubbo团队已经解散(参见http://www.oschina.net/news/55059/druid-1-0-9 中的评论), 反到是当当网的扩展版本仍在持续发展,墙内开花墙外香。其它的一些知名电商如当当、京东、国美维护了自己的分支或者在dubbo的基础开发, 但是官方的库缺乏维护,相关的依赖类比如Spring,Netty还是很老的版本(Spring 3.2.16.RELEASE, netty 3.2.5.Final), 倒是有些网友写了升级Spring和Netty的插件。

Motan是新浪微博开源的一个Java框架。它诞生的比较晚,起于2013年,2016年5月开源。Motan在微博平台中已经广泛应用,每天为数百个服务完成近千亿次的调用。

Rpcx是Go语言生态圈的Dubbo,比Dubbo更轻量,实现了Dubbo的许多特性,借助于Go语言优秀的并发特性和简洁语法,可以使用较少的代码实现分布式的RPC服务。

gRPC是Google开发的高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计, 基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。本身它不是分布式的,所以要实现上面的框架的功能需要进一步的开发。

框架 开发语言 多IDL 分布式(服务治理) 多序列化框架 多注册中心 服务管理
gRPC 跨语言 x(只支持protobuf) x x x x
Thrift 跨语言 x(只支持thrift格式) x x x x
Dubbo Java
motan Java
rpcx Golang

Protobuf

gRPC是基于Protobuf的,那么Protobuf是什么呢?Protobuf是Protocol Buffers的缩写, 是一种与语言以及平台无关的可扩展的序列化结构化的数据的方法,通常用于通信协议或者数据存储等等。 与传统的序列化数据常用的XML,JSON相比,他更轻更快,因此也更受开发人员的青睐。

目前常见的有2和3两个版本的Protobuf。

相比于v2来说v3主要的改动

  • 在第一行必须写 syntax = “proto3”;
  • 删除了required字段
  • 删除了optional字段,默认就是optional
  • 删除了default字段
  • 删除了扩展特性,新增Any类型来替代
  • 删除了unknown字段的支持
  • 新增了JSON Mapping
  • 新增了Map类型的支持
  • 修复enum的unknown类型
  • repeaetd默认使用packed编码,在 proto2 中,需要明确使用 [packed=true] 来为字段指定比较紧凑的 packed 编码方式。
  • 增加了新的语言实现

更详细的功能,可以参阅 Protobuf Version 3

为什么不用XML或者JSON

  • 更简单
  • 数据描述文件只需原来的1/10至1/3
  • 解析速度是原来的20倍至100倍
  • 减少了二义性
  • 生成了更易使用的数据访问类

举例

syntax = "proto3";

service HelloService {
    rpc Hello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message HelloResponse {
    ...
}

1、第一行(非空的非注释行)声明使用 proto3 语法。如果不声明,将默认使用 proto2 语法。同时我建议用 v2 还是 v3,都应当声明其使用的版本

2、定义 HelloService RPC 服务,其包含 RPC 方法 Hello,入参为 HelloRequest 消息,出参为 HelloResponse 消息

3、定义 HelloRequest、HelloResponse 消息,前者定义了三个字段,每一个字段包含三个属性:类型、字段名称、字段编号

4、Protobuf 编译器会根据选择的语言不同,生成相应语言的 Service Interface Code 和 Stubs

最后,这里只是简单的语法介绍,详细的请右拐 Language Guide (proto3)

数据类型

.proto Type C++ Type Java Type Golang Type
double double double float64
float float float float32
int32 int32 int int32
int64 int64 long int64
uint32 uint32 int uint32
uint64 uint64 long uint64
sint32 int32 int int32
sint64 int64 long int64
fixed32 uint32 int uint32
fixed64 uint64 long uint64
sfixed32 int32 int int32
sfixed64 int64 long int64
bool bool boolean bool
string string String string
bytes string ByteString []byte

gRPC特点

  • HTTP/2
  • Protobuf
  • 客户端、服务端基于同一份IDL
  • 对移动网络友好
  • 支持多语言

gRPC支持的语言

  • C++
  • C#
  • Dart
  • Go
  • Java
  • Node.js
  • Objective-C
  • PHP
  • Python
  • Ruby