原文链接:https://mp.weixin.qq.com/s/ah...

 

本文概括性的介绍gRPC,包含gRPC的起源,外围个性,生态体系,以及一些出名开源软件对gRPC的应用,最初总结gRPC与netty、dubbo等框架的区别,目标是让读者从整体上对gRPC有一个绝对全面的认知。

1 gRPC起源

十多年来,Google始终在应用一个名为Stubby的通用RPC基础架构来连贯在数据中心外部和逾越数据中心运行的大量微服务,其外部零碎长期以来始终承受微服务架构的遍及。

领有对立的跨平台RPC基础架构,能够在整个零碎范畴内推广效率,安全性,可靠性和行为剖析,这对于反对Google的惊人增长至关重要。咱们明天应用的每个Google服务背地的RPC骨干都是Stubby。

Stubby有许多很棒的性能 - 然而,它不是基于任何规范,而是与Google的外部基础设施严密耦合,并不适宜公开公布。

随着SPDY,HTTP / 2和QUIC的呈现,许多这些雷同的性能曾经呈现在公共规范中,以及Stubby未提供的其余性能。很显著,是时候重做Stubby以利用这种标准化,并将其适用范围扩大到分布式计算的最初一英里,反对挪动设施(如安卓)、物联网(IOT)、和浏览器连贯到后端服务。

2015年3月,Google决定在公开场合构建下一版Stubby,以便与业界分享教训,并进行相干单干,为Google外部以及外界的微服务构建下一版本的Stubby,也就是本文要介绍的配角gRPC。

2 gRPC介绍     

gRPC是一个古代的开源高性能RPC框架,能够在任何环境中运行。它能够无效地连贯数据中心内和跨数据中心的服务,并提供可插拔的反对,以实现负载平衡(load balancing),调用链追踪(tracing),健康检查(health checking)和身份验证(authentication)。它还实用于分布式计算的最初一英里,用于将设施,挪动应用程序和浏览器连贯到后端服务。 

gRPC的四个外围个性,使得其对开发者有着极大的吸引力:

  • 简略的服务定义
  • 跨平台跨语言
  • 基于http/2双向流传输
  • 可插拔的插件机制

2.1 服务定义    

与许多 RPC 零碎相似,gRPC 也是基于以下理念:定义一个服务,指定其可能被近程调用的办法(蕴含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来解决客户端调用。在客户端领有一个存根(Stub),它提供与服务器雷同的办法。客户端利用能够像调用本地对象一样间接调用另一台不同的机器上服务端利用的办法,其背地会通过RPC通信给服务端发送申请,并取得响应。如下图:

要实现这样的性能,咱们首先要进行服务定义(Service Definition),一些框架中,将定义服务的语法称之为IDL(Interface Definition Language,接口定义语言)。

gRPC 默认应用 Protocol Buffer进行服务定义,这是 Google 开源的一套成熟的构造数据序列化机制(当然也能够应用其余数据格式如 JSON)。

目前Protocol Buffer曾经倒退到proto3,绝对于proto2,它领有轻量简化的语法、一些有用的新性能,并且反对更多新语言。通常倡议在 gRPC 里应用 proto3,因为这样你能够应用 gRPC 反对全副范畴的的语言,并且能防止 proto2 客户端与 proto3 服务端交互时呈现的兼容性问题,反之亦然。

应用Protocol Buffer进行服务定义十分简单明了,咱们能够创立一个.proto文件,依照Protocol Buffer语法编写此文件,如:

        阐明如下:

  1. 定义一个示意申请的HelloRequest,其蕴含一个message字段示意申请内容
  2. 定义一个示意响应的HelloResponse,其蕴含一个message字段示意响应内容
  3. 定义服务HelloService,其提供一个hello办法,以HelloRequest作为办法参数,并返回HelloResponse

思考为什么要在一个文件中进行服务定义?

这次要是为了跨语言。gRPC提供了工具,能够依据服务定义文件,来为不同的平台和语言生成server端和client端的代码,意味着你的服务端和客户端,能够应用不同的语言。例如,笔者最近开发的一个服务,服务端应用go编写,客户端须要反对go、python、java。此时笔者就能够依据这个配置文件,别离生成不同语言的代码。

2.2 跨语言跨平台工作    

gRPC提供了工具,能够为不同的平台、语言,生成对应的client和server代码,使得彼此之间能够通过gRPC进行通信。

通常一个规模较大的公司,技术栈往往不对立,可能会应用多种语言。通过gRPC,服务端咱们能够应用一种语言编写,而客户端能够反对多种语言。

下图演示了服务端应用C++,客户端应用Java和Ruby的交互案例:

截止笔者撰写此文(2019年6月28日),官网反对10种语言,以及linux、mac、windows三种平台,具体如下:

2.3 插件机制  

grpc提供了可插拔的插件机制,或者说是拦截器机制,以对每一次RPC申请进行拦挡。基于此,咱们能够实现一些RPC通信过程中的高级性能。如:

身份验证:

gRPC内置了两种验证机制,基于连贯层面的SSL/TLS,以及基于Google Token的身份认证机制。如果不满足需要,你也很容易的进行扩大本人验证机制。

负载平衡:

在微服务架构中,为了实现容灾、高可用或者程度扩大等目标,通常一个服务都会部署多个节点。客户端在调用时,尽量的将申请扩散在不同的节点上,以实现负载平衡。通常负载平衡有两种模式:1)通过代理,即申请先发送给一个两头代理服务器,例如nginx,由代理依照负载平衡策略抉择一个后端节点进行解决;2) 客户端路由:客户端依照负载平衡抉择某个后端服务节点,进行调用。gRPC提供了一套欠缺的机制,反对客户端发现服务端有哪些节点,以及自定义负载平衡策略。

健康检查:

健康检查用于探测服务端是否能够解决RPC申请。查看查看能够由客户端间接发动,或者通过其余零碎(如consul)。服务端能够抉择回复”unhealthy"来表明本人还没筹备好解决申请,或者服务端曾经宕机。客户端依据服务端回复的响应信息,或者指定工夫内是否收到响应,来判断服务端是否衰弱。

2.4 基于HTTP/2双向流传输    

gRPC 基于 HTTP/2 规范设计,带来诸如双向流、流控、头部压缩、单 TCP 连贯上的多复用申请等特。这些个性使得其在挪动设施上体现更好,更省电和节俭空间占用。

gRPC利用HTTP/2进行音讯传输,然而其只是自身定义了HTTP2中的传输单元中帧(Frame)的格局。至于HTTP/2协定自身的解析,gRPC尽量复用已有的组件。例如,在Java中,Netty自身反对HTTP/2协定协定,因而gRPC默认是反对与netty进行整合的。又或者,如果你心愿挪动设施(如安卓),能够间接与服务端进行交互,那么在安卓客户端,你能够抉择将gRPC与okHttp进行整合。

3 gRPC生态体系

        gRPC有着丰盛的生态系统,这些组件是由不是官网提供。以下介绍局部组件:

  • grpc-opentracing
  • grpc-gateway
  • grpc-prometheus
  • 其余组件

3.1 grpc-opentracing

在RPC调用过程中,可能会呈现A调动B,B又调用C等状况,此时咱们心愿对残缺的调用链路进行追踪。

grpc生态系统中有一个grpc-opentracing组件,咱们能够应用其对接zipkin,进行调用链路展现,查看整个调用链路中每个环节的耗时,以发现零碎的瓶颈。下

图起源自zipkin官网,咱们能够看到链路追踪的最终展现成果:

3.2 grpc-promethus

grpc-prometheus来对gRPC服务进行监控,并将监控数据存储到prometheus中。

目前有2种语言的实现:

  • java-grpc-prometheus
  • go-grpc-prometheus

监控指标服务端与客户端别离统计,统计的指标包含:发动了多少个申请,接管到了多少个响应,响应提早等。

3.3 grpc-gateway

gRPC曾经反对了绝大部分支流语言,对于一些小众语言可能不反对,此时你能够应用grpc-gateway来进行反向代理。

grpc-gateway实质是一个protoc插件,咱们在编写gRPC服务定义proto文件,通过指定一些自定义选项,在编译时,在生成gRPC代码时,额定指定生成grpc-gateway反向代理相干代码,其作用是将RESTful JSON API申请转换为gRPC申请。

之后,咱们对反向代理代码进行革新,对于不反对gRPC的语言,让其发送HTTP RESTful JSON 申请,通过反向代理将其转换成grpc申请,下图演示了其工作原理:

3.4 其余反对

上述提到的几个组件gRPC生态体系中的组件,围绕着gRPC来开发的。一些其余的驰名开源软件,如nginx、haproxy等,也提供了对gRPC的反对。

3.4.1 nginx对gRPC的反对

nginx从1.13.10开始提供对grpc的反对,client端和server端都能够应用gRPC实现,通过nginx进行代理,如下图:

nginx应用grpc_pass指令代理流量。上面的nginx代理配置,演示了在端口80上侦听未加密的gRPC流量并将申请转发到端口50051上的服务器。

更残缺的介绍和配置,点击这里:

https://www.nginx.com/blog/ng...

3.4.2 HAProxy对gRPC的反对

HAProxy 从1.9.2 增加了对gRPC的反对。残缺介绍,点击以下链接:

https://www.haproxy.com/blog/...

4 gRPC应用案例

很多出名公司或者机构目前都应用了gRPC,这些公司对gRPC的应用,自身就证实了其弱小稳固与牢靠。官网列出有以下这些:

这些公司别离在各自的产品中应用了gRPC,上面介绍etcd和tidb。

4.1 etcd案例

etcd是一个牢靠的分布式k/v存储,利用Raft一致性算法,用于存储分布式系统的最要害数据,应用Go语言编写,k8s应用了etcd来存储数据。

etcd v3 应用 gRPC 作为它的音讯协定。etcd 我的项目包含基于 gRPC 的 Go client 和 命令行工具 etcdctl,通过 gRPC 和 etcd 集群通信。另外,对于gRPC不反对的语言,etcd v3通过grpc-gateway(回顾前文)予以反对。

4.2 tidb案例

TiDB 是 PingCAP 公司设计的开源分布式 HTAP (Hybrid Transactional and Analytical Processing) 数据库,联合了传统的 RDBMS 和 NoSQL 的最佳个性。TiDB 兼容 MySQL,反对有限的程度扩大,具备强一致性和高可用性。

TiDB 集群次要包含三个外围组件:TiDB ServerPD Server 和 TiKV Server。此外,还有用于解决用户简单 OLAP 需要的 TiSpark 组件。这些组件之间也应用gRPC来交互,如下图:

图片起源自网络

对于tidb与gRPC的渊源,参考这里(故事比拟波折):

https://blog.csdn.net/weixin_...

5 gRPC性能

之所以有这么多厂商应用gRPC,除了其自身的设计,丰盛的生态体系,与其高性能也有着极大的关系。

gRPC专为分布式应用的高性能和高生产率设计而设计。继续性能基准测试是gRPC开发工作流程的要害局部。目前gRPC会针对master分支每小时运行一次多语言性能测试,并将这些数字报告给仪表板以进行可视化。

测试场景

  • 无争用提早 - 只有1个客户端应用StreamingCall一次发送一条音讯时看到的中位数和尾部响应提早
  • QPS - 当有2个客户端和总共64个通道时的音讯/秒速率,每个通道应用StreamingCall一次发送100个未实现的音讯
  • 可伸缩性(实用于所选语言) - 每个服务器外围的音讯数/秒

下图演示了第二个测试场景下的测试qps:

能够看到,应用go和java时,qps靠近240w/s这个惊人的数字。当然,千万不能齐全置信这个数字,qps受到网络、音讯大小、机器配置等多种因素的综合影响。理论应用还是须要自行测试。

6 总结

本文概括性的介绍gRPC,包含gRPC的起源,外围个性,生态体系,以及一些出名开源软件对gRPC的应用,目标是让读者从整体上对gRPC有一个绝对全面的认知。

补充:gRPC与netty、dubbo等框架的区别

netty实质上是一个高性能的网路通信框架,且局限于Java语言。gRPC则不同,则是面向微服务设计的,netty能够作为gRPC的底层通信框架,gRPC自身还反对很多微服务中的概念,如后面提到的服务发现注册,链路追踪等。

与其余微服务框架如dubbo、spring cloud等,gRPC不局限于某一种语言,而是简直所有支流语言。

另外一个很大的不同是,gRPC不是采纳公有协定,而是基于规范的HTTP/2实现,这意味着可能会有更多的厂商应用或者反对gRPC,如果后面提到的nginx、etcd等。这体现了遵循规范的重要性,试想,如果想要nginx反对dubbo,或者etcd来应用dubbo,简直是不可能的事件。

设计者的思路,间接决定了一门技术到底可能有多宽泛的应用场景


微信公众号【程序员黄小斜】作者是前蚂蚁金服Java工程师,专一分享Java技术干货和求职成长心得,不限于BAT面试,算法、计算机根底、数据库、分布式、spring全家桶、微服务、高并发、JVM、Docker容器,ELK、大数据等。关注后回复【book】支付精选20本Java面试必备精品电子书。