您的当前位置:首页正文

gRPC介绍

2024-11-08 来源:个人技术集锦

gRPC 是一个由谷歌开发的现代开源高性能 RPC 远程过程调用( Remote Procedure Calls)框架,具备良好的兼容性,可在多个开发环境下运行。

相较于目前主流的 HTTP API 接口,gRPC 接口采用了领先的 HTTP/2 底层架构设计作为底层传输协议,能够在大规模数据传输场景(例如视频流传输)和大量服务相互调用的微服务架构场景下大展身手。

数据交换采用轻量化的 Protobuf 序列化协议,使得它能够在资源受限场景(常见于手机等移动端设备)提供更快的数据处理速度的同时,减少网络传输的数据量并节省网络带宽,从而降低功耗并提升电池寿命。

在正式开始介绍 gRPC 之前,我们不妨先弄清楚到底什么是 RPC 以及它的作用,这对于后续的理解十分有帮助。

RPC简介

RPC 协议是一种远程过程调用的实现方式。假设现在有两台服务器 A 和 B。部署在 A 服务器上的服务,想调用正在 B 服务器上运行的另一个进程。但由于双方服务并不在一个内存空间而导致无法直接调用,那么就必须通过网络通讯来达到调用效果。

要建立网络通讯的无非是在传输层发起 TCP 连接。TCP 的握手机制确保了数据包能可靠地传输给对方,并且它具备以下三个特点:面向连接、可靠、基于字节流。前面两种特性都可以胜任这个场景,但唯独在基于字节流这一点恐怕值得商榷。为什么?

因为它没有边界。字节流本质上是在传输层双向通道中流淌的数据,也就是计算机能够理解的二进制 0 1 数据。所以当发送端使用 TCP 发送“南京市”+“长江大桥”字符时,接收端有可能收到的就是“南京市长”+“江大桥”,也有可能是“南京市长江大桥”等。

过于简单的 TCP 连接过程无法保证信息的唯一性和确定性,因此才需要在数据中定义消息头、消息体,并且发送方与接收方共同认可这套沟通方式,由此衍生出了 HTTP 协议和 RPC 调用等方案,它们本质上都是对数据的传递和调用方式作出了规范化定义,避免出现信息失真。

例如现在有一个购物网站,存在订单服务与用户服务(例如账号管理)两项微服务。订单服务需要使用函数查询到用户服务下的一些数据,但是两者相隔离。此时订单服务就必须通过远程调用方式获取数据。

下图的示例中,服务端(用户服务)仅需暴露出一个能够调用数据库的 getConsumerByld() 函数,客户端(订单服务)使用 RPC 便能够像在本地中直接调用 getConsumerByld() 函数并获取到所需的响应结果。RPC 成功隐藏了内部通信的复杂性,为双方提供了稳定统一的接口,使得开发者只需要关注业务逻辑,而无需关注底层网络通信细节。

RPC的传输过程

RPC 主要分为三层:

  • 用户和服务器(负责处理业务逻辑,调用本地 Stub)
  • Stub 处理客户端和服务端约定好的语法、语义的封装和解封装
  • RPCRuntime 负责最底层的网络传输

在上述过程中,客户端和服务器端之间的通信可以使用不同的传输协议,如 TCP、HTTP、UDP 等。同时,RPC 的实现也可以采用不同的技术,如 CORBA、Java RMI、gRPC 等。

RPC的优点

  • 简化分布式系统的开发:RPC可以隐藏底层的网络细节,使得开发人员可以专注于业务逻辑的实现,而不必考虑网络通信的细节。
  • 提高系统的可扩展性:RPC可以将系统的不同部分分布在不同的机器上,从而使系统更容易扩展,以满足不断增长的需求。
  • 提高系统的可靠性:RPC可以通过将系统的不同部分分布在不同的机器上来实现冗余和备份,从而提高系统的可靠性和容错性。
  • 提高系统的性能:RPC可以通过将计算任务分布在多台机器上来提高系统的处理能力和吞吐量,从而提高系统的性能。
  • 支持多种编程语言和平台:RPC可以跨越不同的编程语言和操作系统平台,使得不同的系统可以进行通信和数据交换,从而提高系统的互操作性。

RPC的应用场景

  1. 分布式系统:在分布式系统中,不同的节点需要进行相互通信,RPC可以实现远程过程调用,使得不同的节点可以相互调用函数或方法,从而实现分布式系统的协同工作。
  2. 微服务架构:在微服务架构中,服务之间需要相互调用,RPC可以实现服务之间的远程过程调用,从而实现微服务之间的协同工作。
  3. 高性能计算:在高性能计算中,需要进行大量的计算,RPC可以将计算任务分发到不同的计算节点上,并通过远程过程调用实现任务的协同计算,从而提高计算效率。
  4. Web应用程序:在Web应用程序中,需要进行大量的数据交互,RPC可以实现客户端与服务器之间的远程过程调用,从而实现数据的传输和处理。
  5. 云计算和容器化部署:在云计算和容器化部署中,往往需要将不同的服务部署在不同的节点上,通过 RPC 框架实现不同节点之间的通信,可以提高系统的可伸缩性和可靠性。

而 gRPC 本质上就是一种由谷歌发布并开源的 RPC 框架。因此很自然拥有上述 RPC 框架的各个优势,面向的场景也是类似的。

gRPC介绍

gRPC是由google开源的高性能的RPC框架。它是由google的Stubby这样一个内部的RPC框架演化出来,gRPC2015年开源,目前是在云原生时代的一个RPC的标准。

gRPC是一种用于实现RPC API的技术。由于gRPC是开源框架,通信双方都基于该框架进行二次开发,从而使得通信双方聚焦在业务,无需关注由gRPC软件框架实现的底层通信。如下图,DATA部分即为业务层面内容,DATA下面所有的信息都由gRPC进行封装。

gRPC的核心设计思路

  • 协议:使用Http2协议(传输数据使用二进制数据内容、支持双向流[双工]、连接的多路复用)
  • 序列化:基于二进制(protobuf- 谷歌开源的一种序列化方式)
  • 代理的创建 :让调用者像调本地方法一样去调用远端的方法

1,使用 http2 协议

HTTP/2 在同年较 gRPC 稍早前发布,因此 gRPC 很自然的将这一先进的传输协议作为底层基础,从而使得它具备更高效的传输性能,并且还能够支持流式调用,为许多实时数据传输场景(例如股票数据、语音通讯、游戏场景)提供支持,天然领先许多在千禧年之际发布的古早 RPC 框架。发起连接时会建立连接池,面对多条连接时能够显著提升网络请求性能。

gRPC 的优点自然也包含了HTTP2 的优点:

  • 二进制分帧

HTTP/2所有性能增强的核心在于新的二进制分帧层,如下图所示,它是所有其他功能和性能优化的基础,它定义了如何封装HTTP消息并在客户端与服务器之间传输。关键之⼀就是在应⽤层(HTTP/2)和传输层(TCP or UDP)之间增加⼀个⼆进制分帧层。如图:

在⼆进制分帧层中, HTTP/2 会将所有传输的信息分割为更⼩的消息并封装在帧(frame)中,并对它们采⽤⼆进制格式的编码 ,其中 HTTP1.1的⾸部信息会被封装到 HEADER frame,⽽相应的 Request Body 则封装到 DATA frame ⾥⾯。如上图的HEADER frame和DATA frame分别对应http1.1的请求头和请求体:

HTTP/2没有改动HTTP的应用语义,仍然使用HTTP的请求方法、状态码和头字段等规则,它主要修改了HTTP的报文传输格式。
HTTP/1.1协议以换行符作为纯文本的分隔符,而HTTP/2将所有传输的信息分割为更小的消息和帧,并采用二进制格式对它们编码,这些帧对应着特定数据流中的消息,他们都在一个TCP连接内复用。

  • 优先级排序

将HTTP消息分解为很多独立的帧之后就可以复用多个数据流中的帧,客户端和服务器交错发送和传输这些帧的顺序就成为关键的性能决定因素。HTTP/2允许每个数据流都有一个关联的权重和依赖关系,数据流依赖关系和权重的组合明确表达了资源优先级,这是一种用于提升浏览性能的关键功能。HTTP/2协议还允许客户端随时更新这些优先级,我们可以根据用户互动和其他信号更改依赖关系和重新分配权重,这进一步优化了浏览器性能。

  • 首部压缩

HTTP每次请求或响应都会携带首部信息用于描述资源属性。HTTP/1.1使用文本的形式传输消息头,消息头中携带cookie每次都需要重复传输几百到几千的字节,这十分占用资源。

HTTP/2使用了HPACK算法来压缩头字段,这种压缩格式对传输的头字段进行编码,减少了头字段的大小。同时,在两端维护了索引表,用于记录出现过的头字段,后面在传输过程中就可以传输已经记录过的头字段的索引号,对端收到数据后就可以通过索引号找到对应的值。

  • 多路复用

多路复用允许同时通过单一的HTTP/2连接发起多重的请求-响应消息,实现多流并行而并不依赖多个TCP连接,HTTP/2把HTTP协议通信的基本单位缩小为一个一个的帧,这些帧对应着逻辑流中的消息,并行地在同一个TCP连接上双向交换消息。

HTTP/2基于二进制分帧层,HTTP/2可以在共享TCP连接的基础上同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息本身的语义交错发出去,在另一端根据流标识符和首部将他们重新组装起来。通过多路复用技术,可以避免HTTP旧版本的消息头阻塞问题,极大提高传输性能。

  • 服务器推送

HTTP2.0的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确的请求。服务端根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。如下图所示,客户端请求stream 1,服务端在返回stream 1的消息的同时推送了stream 2和stream 4。

服务端推送是一种在客户端请求之前发送数据的机制。在HTTP/2中,服务器可以对一个客户端的请求发送多个响应。如果一个请求是由你的主页发送的,服务器可能会响应主页内容、logo以及样式表,因为服务端知道客户端会用到这些东西。这样不但减轻了数据传送冗余步骤,也加快了页面响应的速度,提高了用户体验。

2,序列化:基于二进制(protocol buffers)

Protocol Buffers ( Protobuf ) 是一种免费开源的跨平台数据格式,用于序列化结构化数据。对于开发通过网络相互通信或存储数据的程序很有用。
它是一种数据表达方式,以 .proto 结尾的数据文件,我们可以将其类比为 json、xml 等文件。
其优点在于,编解码速度更快且传输的数据更小。

Protocol Buffers 的优点:

  • 性能好/效率高:时间和空间开销较少
  • 有代码生成机制:protobuf可以自动生成它的.h 文件和点.cpp文件。protobuf将对结构体testA的操作封装成一个类
  • 支持向后兼容和向前兼容:当客户端和服务器同事使用一块协议的时候, 当客户端在协议中增加一个字节,并不会影响客户端的使用
  • 支持多种编程语言:在Google官方发布的源代码中包含了c++、java、Python三种语言

Protobuf 的缺点:

  • 二进制格式导致可读性差:为了提高性能,protobuf采用了二进制格式进行编码。这直接导致了可读性差。这个直接影响开发测试时候的效率。当然,一般情况下,protobuf非常可靠,并不会出现太大的问题。
  • 缺乏自描述:一般来说,XML是自描述的,而protobuf格式则不是。 给你一段二进制格式的协议内容,不配合你写的结构体是看不出来什么作用的。
  • 通用性差:protobuf虽然支持了大量语言的序列化和反序列化,但仍然并不是一个跨平台和语言的传输标准。在多平台消息传递中,对其他项目的兼容性并不是很好,需要做相应的适配改造工作。相比json 和 XML,通用性还是没那么好。

gRPC VS Thrift

首先Thrift和gRPC这两个RPC框架有一个共性,就是都支持异构语言的RPC

  • 网络通信层面:Thrift自己定义了自己的协议,直接基于TCP协议,而gRPC的协议是HTTP2的协议
  • 性能角度:ThriftRPC的效率是高于gRPC
  • gRPC是大厂背书(google),云原生时代gRPC与其它组件合作的更加好,所以gRPC应用的更广泛

gRPC VS REST

REST(Representational State Transfer)表征状态转移,是一种软件架构风格,用于指导WEB架构的设计和开发。REST同样为管理和配置网络设备提供了一种API接口设计的方法。gRPC与REST两者的主要差异如下:

  • REST遵循基于HTTP 1.1的请求-响应通信模型,而gRPC遵循基于HTTP 2.0的客户端-响应通信模型。
    HTTP 2.0相对于HTTP 1.1,在速度上有着绝对的优势。虽然REST也可以基于HTTP 2.0进行数据传输,但是为了兼容HTTP 1.1方式,导致其没有充分利用HTTP 2.0的优势。
  • 几乎所有的浏览器都支持REST,而支持gRPC的浏览器非常有限。这是REST相对于gRPC的主要优势。
  • REST使用JSON或XML编码格式承载数据,而gRPC默认使用ProtoBuf(Protocol Buffers)编码格式承载数据。
    ProtoBuf是二进制的,是以二进制数据进行传输,而JSON或XML编码格式以文本形式传输,所以在传输速率上gRPC更具有优势。
  • REST不提供内置代码生成功能,需要使用Swagger等工具生成API请求代码。而gRPC具有protoc编译器,具有代码生成功能,而且protoc编译器与多种编程语言兼容。

gRPC的优点:

  • 能够高效的进行进程间通信(协议+序列化)
  • 支持多种语言,对主流的语言提供了原生的支持(C、GO、Java)
  • 支持多平台运行(Linux、Android、IOS、Mac1OS、Windows)
  • grpc序列化方式使用prorubuf、效率高
  • 使用Http2协议

参考:
https://juejin.cn/post/7360520652519161894
https://apifox.com/blog/grpc-and-rpc-debugging/?utm_source=google_search&utm_medium=g&utm_campaign=15676663585&utm_content=137784982731&utm_term=&gad_source=1&gclid=EAIaIQobChMIt_aZ6sbOiAMVpl8PAh08vSQFEAMYASAAEgJE5vD_BwE

Top