GRPC
GRPC is A high-performance, open-source universal RPC framework.
是什么
在gRPC里客户端应用可以像调用本地对象一样直接调用另一台不同机器上服务端应用的方法,使得你能够更容易地创建分布式应用和服务。
与许多RPC系统类似,gRPC也是基于以下理念:
定义一个服务,指定其能够被远程调用的方法(包括参数和返回类型)。
在服务端实现这个接口,并运行一个gRPC服务器来处理客户端调用。
在客户端拥有一个存根能够像服务端一样的方法。
特性
- 基于HTTP/2
HTTP/2 提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。可以节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。gRPC 的协议设计上使用了HTTP2 现有的语义,请求和响应的数据使用HTTP Body 发送,其他的控制信息则用Header 表示。
- IDL使用ProtoBuf
gRPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议(类似于XML、JSON、hessian)。ProtoBuf能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。压缩和传输效率高,语法简单,表达力强。
- 多语言支持(C, C++, Python, PHP, Nodejs, C#, Objective-C、Golang、Java)
gRPC支持多种语言,并能够基于语言自动生成客户端和服务端功能库。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它语言的版本正在积极开发中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等语言,grpc-java已经支持Android开发。
应用场景
gRPC已经应用在Google的云服务和对外提供的API中,其主要应用场景如下:
-
低延迟、高扩展性、分布式的系统
-
同云服务器进行通信的移动应用客户端
-
设计语言独立、高效、精确的新协议
-
便于各方面扩展的分层设计,如认证、负载均衡、日志记录、监控等
缺陷
缺点:
1)GRPC尚未提供连接池,需要自行实现
2)尚未提供“服务发现”、“负载均衡”机制
3)因为基于HTTP2,绝大部多数HTTP Server、Nginx都尚不支持,即Nginx不能将GRPC请求作为HTTP请求来负载均衡,而是作为普通的TCP请求。(nginx1.9版本已支持)
4) Protobuf二进制可读性差(貌似提供了Text_Fromat功能)
默认不具备动态特性(可以通过动态定义生成消息类型或者动态编译支持)
为什么高效
个人认为:gRPC之所以高效,除了在协议层使用Protobuffer之外,底层使用HTTP/2也是一个非常重要的原因。
下面先上一张图,再来看看HTTP/2的一些特征。
对比其他语言
与thrift,dubbo,motan等比较
* Motan Dubbox thrift gRPC rpcx
开发语言 Java Java 跨语言 跨语言 go
分布式服务治理 Y Y 可以配合zookeeper, Eureka等实现 可以配合etcd(go),zookeeper,consul等实现 自带服务注册中心,也支持zookerper,etcd等发现方式
底层协议 motan协议,使用tcp长连接 Dubbo 协议、 Rmi 协议、 Hessian 协议、 HTTP 协议、 WebService 协议、Dubbo Thrift 协议、Memcached 协议 tpc/http/frame http2 tcp长链接
消息序列化 hessian2,json hessian2,json,resr,kyro,FST等,可扩展protobuf等 thrift protobuf Gob、Json、MessagePack、gencode、ProtoBuf等
跨语言编程 N(支持php client和c server) N Y Y N
负载均衡 ActiveWeight 、Random 、 RoundRobin 、LocalFirst 、 Consistent 、ConfigurableWeight Random 、RoundRobin 、ConsistentHash 、 LeastActive Haproxy, zookerper+客户端负载均衡等方案 负载均衡软件HaProxy等 支持随机请求、轮询、低并发优先、一致性 Hash等
容错 Failover 失效切换、Failfast 快速失败 Failover 、 Failfast 、Failsafe 、 Failback 、 Forking、 Broadcast Failover 具有 Failover 失效切换的容错策略 失败重试(Failover)、快速失败(Failfast)
注册中心 consul zookeeper zookeeper etcd,zookeeper,consul zookerper,etcd
性能 ★★ ★★ ★★★★ 比grpc快2-5倍 ★★★ 比dubbox,motan快 ★★★★★ 比thrift快1-1.5倍
侧重优势 服务管理 服务管理 跨语言,性能++ 跨语言,性能 性能++,服务治理
客户端异步调用方案
使用thrift IDL “oneway” 关键字(无返回结果),+callback
tcp异步请求
- thrift IDL参数不支持函数或服务
stream传输,双向通信
服务端异步处理 1、TNonblockingServer(java/c++,php); THsHaServer(java/c++); TThreadpoolServer(java/c++); TThreadSelectorServer(java/c++)
2、结合消息队列或中间件
3、swoole/goroutine等多任务支持 同上,使用stream传输。Stream对象在传输过程中会被当做集合,用Iterator来遍历处理
java 快速开始
参考 java 快速开始
个人收获
技术生态多样性
对于 rpc 的学习,在工作中使用一个即可。
比如 dubbo,或者 spring cloud。
服务治理,远程调用的核心原理才是需要掌握的。
学习其中的一个即可。相似的方案总是多样的。永远也学不完,更会浪费时间。
比如mq,就各种各样。但是原理就是两次 rcp+broker。
全部与专门
比如 dubbo 是专门针对 java 的 rpc 框架,那 java 开发者使用起来就相对方便。对于其他语言的开发者则无法直接使用。
而 grpc 是所有语言都支持,这就导致特定的语言在使用时语言使用一次生成代码,有利也有弊。
性能的质变
有时候在代码层面的小优化,是无法战胜协议层的优化。
比如 http/2 优于 http
protocal 优于 json
这种优势不是写代码就能优化的。
拓展阅读
- rpc
- 序列化协议
- 网络协议
参考资料
- java