gRPC基础讲解

一、gRPC原理

1、什么是RPC

RPC 即远程过程调用协议(Remote Procedure Call Protocol),可以让我们像调用本地函数一样发起远程调用。RPC 凭借其强大的治理功能,成为解决分布式系统通信问题的一大利器。

gRPC是一个现代的、高性能、开源的和语言无关的通用 RPC 框架(g就是谷歌的意思),基于 HTTP2 协议设计,序列化使用 PB(Protocol Buffer),PB 是一种语言无关的高性能序列化框架,基于 HTTP2+PB 保证了的高性能。

上面的图就是一个客户端远程连接一个服务器,调用它的函数。由于使用了 PB 所以双方都要有 PB 序列化和反序列化。那么上面的操作就是通过PB序列化后,通过网络HTTP2发送给服务端,然后解析并执行,最后返回。

2、gRPC的特性

  1. gRPC基于服务的思想:定义一个服务,描述这个服务的方法以及入参出参,服务器端有这个服务的具体实现,客户端保有一个存根,提供与服务端相同的服务。

  2. gRPC默认采用protocol buffer作为IDL(Interface Description Lanage)接口描述语言,服务之间通信的数据序列化和反序列化也是基于protocol buffer的,因为protocol buffer的特殊性,所以gRPC 框架是跨语言的通信框架(与编程语言无关性),也就是说用Java开发的基于gRPC的服务,可以用 GoLang编程语言调用。

  3. gRPC同时支持同步调用和异步调用,同步RPC调用时会一直阻塞直到服务端处理完成返回结果, 异步RPC是客户端调用服务端时不等待服务段处理完成返回,而是服务端处理完成后主动回调客户端告诉客户端处理完成。

  4. gRPC是基于http2协议实现的,http2协议提供了很多新的特性,并且在性能上也比http1提搞了许多,所以gRPC的性能是非常好的。

  5. gRPC并没有直接实现负载均衡和服务发现的功能,但是已经提供了自己的设计思路。已经为命名 解析和负载均衡提供了接口。

  6. 基于http2协议的特性:gRPC允许定义如下四类服务方法:

  1. 一元RPC:客户端发送一次请求,等待服务端响应结构,会话结束,就像一次普通的函数调用这样简单。

  2. 服务端流式RPC:客户端发起一起请求,服务端会返回一个流,客户端会从流中读取一系列消息,直到没有结果为止。

  3. 客户端流式RPC:客户端提供一个数据流并写入消息发给服务端,一旦客户端发送完毕,就等待服务器读取这些消息并返回应答。

  4. 双向流式RPC:客户端和服务端都一个数据流,都可以通过各自的流进行读写数据,这两个流是相互独立的,客户端和服务端都可以按其希望的任意顺序读写。

3、gRPC的使用场景

服务间通信:gRPC非常适合用于微服务架构中,为服务之间的通信提供高性能、类型安全和易于维护的通信机制。它支持多种编程语言,使得不同微服务可以使用不同的编程语言实现,同时轻松地进行跨语言通信。

分布式系统通信:在分布式系统中,gRPC可用于不同节点之间的通信,包括数据同步、任务分发和集群管理等场景。

4、gRPC设计的动机

1、协议可插拔:不同的服务可能需要使用不同的消息通信类型和编码机制,例如,JSON、XML和 Thirft,所以协议应允许可插拔机制,还有负载均衡,服务发现,日志,监控等都支持可插拔机制。

2、阻塞和非阻塞:支持客户端和服务器交换的消息序列的异步和同步处理。这对于在某些平台上扩展和处理至关重要。

3、流处理:存储系统依靠流和流控制来表达大型数据集,其他服务,如语音到文本或股票行情,依赖于流来表示与时间相关的消息序列。

4、流控制:计算能力和网络容量在客户端和服务器之间通常是不平衡的。流控制允许更好的缓冲区管理,以及过度活跃的对等体提供对DOS的保护。

5、互通性:报文协议必须遵循普通互联网基础框架。

二、数据封装和数据传输问题

1、网络传输中的内容封装数据体积问题

我们都知道json格式,json格式更利于人的观看,而Protobuf是二进制数据,更加利于机器。

JSON

优点:在body中用JSON对内容进行编码,极易跨语言,不需要约定特定的复杂编码格式和Stub文件。 在版本兼容性上非常友好,扩展也很容易。

缺点:JSON难以表达复杂的参数类型,如结构体等;数据冗余和低压缩率使得传输性能差。

因此gRPC丢弃json、xml这种传统策略,使用 Protocol Buffer,gRPC是Google开发的一种跨语言、跨平台、可扩展的用于序列化数据协议。

2、HTTP效率

HTTP1.0:每个请求都需要与服务器建立一个新的TCP连接,并且在请求完成后立即关闭连接。这意味着如果需要发送多个请求,就需要建立多个TCP连接,这会增加网络开销和延迟。尽管HTTP1.0默认使用无连接,但通过在请求头中设置Connection字段为Keep-Alive,可以保持TCP连接不断开,从而减少网络开销和延迟。

HTTP1.1 Pipeline(顺序):默认支持长连接,允许在同一个TCP连接中发送多个请求和接收多个响应,但是在同一个TCP连接中,没办法区分response是属于哪个请求,一旦多个请求返回的文本内容混在一起,则没法区分数据归属于哪个请求,所以请求只能一个个串行排队发送(管道化技术)。这直接导致了TCP资源的闲置。虽然服务器仍然需要按照请求的顺序发送响应,但管道化技术可以减少网络延迟和提高传输效率。

HTTP2.0Duplexing (谁快谁先):提出了流的概念,每一次请求对应一个流,有一个唯一ID,用来区分不同的请求。基于流的概念,进一步提出了 帧 ,一个请求的数据会被分成多个帧,方便进行数据分割传输,每个帧都唯一属于某一个流ID,将帧按照流ID进行分组,即可分离出不同的请求。这样同一个TCP连接中就可以同时并发多个请求,不同请求的帧数据可穿插在一起,根据流ID分组即可。HTTP2.0基于这种二 进制协议的乱序模式 (Duplexing),直接解决了HTTP1.1的核心痛点,通过这种复用TCP连接的方式,不用再同时建多个连接,提升了TCP的利用效率。

gRPC采用HTTP2.0,相对于HTTP1.0 在更快的传输更低的成本两个目标上做了改进。有以下几个基本点:

HTTP2 未改变HTTP的语义(如GET/POST等),只是在传输上做了优化。

引入帧、流的概念,在TCP连接中,可以区分出多个request/response。

一个域名只会有一个TCP连接,借助帧、流可以实现多路复用,降低资源消耗。

引入二进制编码,降低header带来的空间占用。

三、gPRC四种模式

1、一元RPC模式

一元 RPC 模式也被称为简单 RPC 模式。在该模式中,当客户端调用服务器端的远程方法时,客户端发送请求至服务器端并获得一个响应,与响应一起发送的还有状态细节以及 trailer 元数据。

2、服务器端流RPC模式

在一元 RPC 模式中,gRPC 服务器端和 gRPC 客户端在通信时始终只有一个请求和一个响应。在服务器端流 RPC 模式中,服务器端在接收到客户端的请求消息后,会发回一个响应的序列。这种多个响应所组成的序列也被称为"流"。在将所有的服务器端响应发送完毕之后,服务器端会以 trailer 元数据的形式将其状态发送给客户端,从而标记流的结束。

比如我们搜索一块地方的全部旅游景点,我们发送一个请求,那么会返回多个旅游景点。

3、客户端流RPC模式

在客户端流 RPC 模式中,客户端会发送多个请求给服务器端,而不再是单个请求。服务器端则会发送一个响应给客户端。但是,服务器端不一定要等到从客户端接收到所有消息后才发送响应。基于这样的逻 辑,我们可以在接收到流中的一条消息或几条消息之后就发送响应,也可以在读取完流中的所有消息之后再发送响应。

客户端流RPC模式,适用于客户端需要连续发送大量数据的场景。

4、双向流RPC模式

在双向流 RPC 模式中,客户端以消息流的形式发送请求到服务器端,服务器端也以消息流的形式进行响应。调用必须由客户端发起,但在此之后,通信完全基于 gRPC 客户端和服务器端的应用程序逻辑。

本期gRPC的基础讲解完毕,后面我会出gRPC同步和异步的代码讲解。0voice · GitHub

相关推荐
ktkiko114 小时前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
点点滴滴的记录18 小时前
RPC核心实现原理
网络·网络协议·rpc
徒步僧18 小时前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc
zfoo-framework2 天前
游戏中Dubbo类的RPC设计时的注意要点
网络·网络协议·rpc
帅气的人1233 天前
thrift rpc 四种类型的服务端的实现详细介绍
java·开发语言·网络·网络协议·rpc
eaglewgs5 天前
浅谈RPC的实现原理与RPC实战
网络·网络协议·rpc
菜鸟起航ing6 天前
Apache Dubbo (RPC框架)
rpc·apache·dubbo
帅气的人1236 天前
thrift idl 语言基础学习
java·开发语言·python·rpc·go·thrfit
一片蓝蓝的云7 天前
实现RPC接口的demo记录
网络·网络协议·rpc
Likelong~7 天前
设计一个灵活的RPC架构
网络协议·rpc·架构