目录

GRPC简介

目录

1. 计算机通信协议

根据OSI(Open System Interconnection)参考模型,计算机或通信系统间互联的标准体系有七层:

1.物理层:将数据转换为可通过物理介质传送的0和1电子信号,管理通信设备和网络媒体之间的互联互通。通俗来说就是将电脑连接起来的物理手段,包括光缆、电缆、无线电等。

2.数据链路层:决定访问网络介质的方式,可以提供介质访问、链路管理等,常见的比如以太网、网卡、交换机、PPTP(点对点隧道协议,Point to Point Tunneling Protocol)、L2TP(第二层隧道协议,Layer Two Tunneling Protocol)等。

3.网络层:负责IP选址与路由选择,它可以为报文或通信子网选择最适当的路径,控制数据链路层与传输层之间的信息转发,建立、维持和终止网络的连接,常见的比如IP(IPV4/IPV6,互联网协议)、ICMP(互联网控制信息协议)、IGMP(组管理协议)。

4.传输层:提供终端到终端的可靠连接,用于数据通信,可以为会话层与网络层提供端到端可靠透明的数据传输服务,确保数据能完整被传输到网络层。常见的比如TCP(控制传输协议,Transmission Control Protocol)、UDP(用户数据报协议、User Datagram Protocol)。

5.会话层:创建、管理和维护会话,它可以接收来自传输层的数据,建立、管理和终止表示层实体之间的通信会话。常见的有SSL(安全套接字层协议)、TLS(安全传输层协议)。

6.表示层:负责数据编码、格式转换与数据加密,可以提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。常见的比如LPP(轻量级表示协议)。

7.应用层:为应用程序或用户请求提供各种请求服务,可以为计算机用户、各种应用程序以及网络提供接口,也为用户直接提供各种网络服务。常见的比如HTTP(超文本传输协议)、HTTPS(超文本传输安全协议)、DNS(域名系统)、FTP(文本传输协议)。

2. RPC

大多数的计算机通信协议都基于TCPUDP协议生成,它们是计算机网络中最常用的两种传输层协议,可以提供不同的数据传输方式以满足不同的应用需求。

TCP的三个特点是面向连接、可靠、基于字节流(顺便一提,UDP的三个特点是无连接、不可靠、面向数据报),但使用纯裸TCP容易出现粘包问题等,需要在它的基础上加入一些自定义规则用于区分消息边界。例如常见的可以将消息包装成消息头+消息体的形式:

/images/1.jpg

这其中消息头可以包含多种信息,例如完整的包长度、消息体是否被压缩过、消息体格式等等,只要通信体系的上下游均约定好特定的消息头,就可以实现互认,这也就是所谓的协议。也正是由此,基于TCP衍生出众多协议,其中就包含多种RPC协议。

准确来说,RPC(远程过程调用,Remote Procedure Call)本身并不是一个具体的协议,而是一种调用方式,它可以帮助我们调用远程计算机上某个服务的方法,使得调用远程方法与调用本地方法一样简单。举例而言,如果有两个不同的服务AB,它们分别部署在不同的机器上,此时若要在服务A中调用服务B中的某个方法,就可以使用RPC

RPC的原理图如下:

/images/2.jpg

我们可以将整个框架看作五个主要部分:

1.客户端(服务消费端,client):调用远程方法的一段。

2.客户端桩(client stub):其实就是一个代理类,可以把客户端调用的方法、类、方法参数等信息传递到服务端。

3.网络传输:可以把客户端调用的方法信息等各种参数传输到服务端,服务端执行完后再把结果传输回客户端。网络传输的实现方式有很多,例如SocketNetty(推荐)等。

4.服务端桩(server stub):这里并不是代理类,服务端桩实际指的是接收到客户端执行方法的请求后,去执行对应的方法然后返回结果给客户端的类。

5.服务端(服务提供端,server):提供远程方法的一段。

整个RPC执行的流程如下:

1.客户端以本地调用的方式调用远程远程服务。

2.客户端桩接收到调用指令后将方法、参数等组装成能够进行网络传输的消息体(序列化):RpcRequest

3.客户端桩找到远端服务的地址,并利用网络传输将消息发送到服务提供段。

4.服务端桩接收到消息后将消息反序列化为Java对象:RpcRequest

5.服务端桩根据RpcRequest中的类、方法、方法参数等信息调用本地的方法。

6.服务端桩得到方法执行结果并将其组装成能够进行网络传输的消息体:RpcResponse(序列化)发送至客户端。

7.客户端桩接收到消息并将消息反序列化为Java对象:RpcResponse,得到最终的结果并发送给客户端。

有不少框架的实现都基于RPC调用方式:常见的比如DubboThriftMotangRPC等。

注意:

1.RPC并不是协议,而是一种调用方式,RPC的具体实现比如DubbogRPC等框架才是协议。

2.RPC的实现方式有很多(也就是基于RPC实现方式的框架数量很多),因此不是所有的都基于TCP协议,例如RESTful API是基于HTTP协议的RPC框架,gRPC既可以基于TCP也可以基于UDP。当然,绝大多数RPC协议都是基于TCP协议的,原因是TCP协议提供了可靠、面向连接、流式的传输服务,适合在大部分场景下使用。

3. gRPC

gRPC(Google Remote Procedure Call)是一个高性能、通用的开源RPC框架,面向移动和HTTP/2设计,由Google公司于2015年开发,它支持多种编程语言与底层协议,并且可以提供强大的IDL(交互式数据语言)语言和代码生成工具。它使用基于Protocol BuffersIDL语言来定义服务接口和数据类型,并使用底层协议来实现跨语言的RPC通信。gRPC基于HTTP/2标准设计,带来注入双向流、流控、头部压缩、单TCP连接上的多复用请求等特性,这使得它在移动设备上表现的更好,更节省电与空间占用。

概括下来,gRPC主要包括以下特点:

1.高性能:gRPC使用基于HTTP/2的二进制编码协议,可以提供更高的传输效率和可靠性。

2.跨语言支持:gPRC支持多种语言,包括C++JavaPythonGoKotlinPHPNode.jsC#等。

3.强类型IDLgRPC使用Protocol Buffers作为IDL语言,可以定义服务接口和数据类型,并生成对应的代码,可以简化开发者的工作。

4.流式处理:gRPC支持流式处理,可以实现服务器端流式和客户端流式,适用于大数据量的场景。

5.安全性:gPRC支持TLS/SSL加密协议,可以保证数据的安全性和完整性。

gRPC官方网站

gRPCGitHub仓库

gRPC官方文档中文翻译版

由于gRPC是一种PRC框架,因此它的具体运行流程也与RPC框架类似:

定义一个服务端,指定其能够被远程调用的方法(包括参数和返回类型)。在服务端实现这个接口,并运行一个gRPC服务器(gRPC Server)来处理客户端的调用,在客户端中有一个gPRC桩(gRPC Stub)提供与服务器相同的方法。

gRPC客户端和服务端可以在多种环境中运行和交互,并且可以使用任何gRPC支持的语言编写。你可以选择用Java编写gRPC服务端,同时可以用GoPython等其他语言创建客户端。此外,Google最新的API也包含了gRPC版本的接口,可以让使用者较为容易的将Google的功能集成入应用中。

gRPC采用名为协议缓冲区(Protocol Buffers,可以简称为ProtoBuf)的开放源代码技术,提供极为高效且不受平台影响的序列化格式,用于序列化服务相互发送的结构化消息。它与XMLJSON类似,是一种更加灵活高效的数据格式,可以用于通讯协议、数据存储等领域,基本支持所有主流编程语言且与平台无关,在一些高性能且对响应速度有要求的数据传输场景非常使用。

ProtoBufgRPC框架中可以起到的作用有:定义数据结构、定义服务接口、通过序列化与反序列化方式提升传输效率。

在使用XMLJSON进行数据编译时,数据文本格式更容易阅读,但进行数据交换时,设备就需要耗费大量的CPUI/O操作上,这样会影响整个传输效率。但ProtoBuf不同于它们,它会将字符串进行序列化后再进行传输,即二进制数据。

/images/4.png

可以看出二者的内容差异并不大,但是ProtoBuf的编码内容只是提供给操作者阅读的,实际传输的并不是以这种文本形式,而是序列化后的二进制数据,字节数会比JSONXML的字节数少的多,速率更快。

与采用文本格式的JSON相比,采用二进制格式的ProtoBuf在速度上可以达到前者的5倍。

基于ProtoBuf,可以得到gRPC开发的核心:.proto文件,它定义了gRPC服务和消息的约定。根据这个文件,gRPC框架可以生成服务基类,消息以及完整的客户端代码。

通过在服务端于客户端之间共享.proto文件,可以从端到端生成消息和客户端代码。生成客户端代码可以消除客户端和服务器上的重复消息,并为用户创建一个强类型的客户端,这样可以在具有较多服务和应用程序中节省大量开发时间。

Protocol Buffers官方文档

Protocol Buffers的GitHub仓库

gRPC大致的请求流程如下:

/images/3.png

1.客户端中的gRPC桩(gRPC Stub)调用一个方法A,发起RPC调用请求。

2.gPRC桩对请求信息使用ProtoBuf进行对象序列化压缩(IDL),得到Proto Request

3.gRPC服务端(gRPC Server)接收到请求后,解码请求体,进行业务逻辑处理并返回。

4.gRPC服务端对响应结果使用ProtoBuf进行对象序列化压缩(IDL),得到Proto Response

5.客户端中的gRPC桩接收到Proto Response,解码请求体,回调被调用的方法A,唤醒正在等待响应(阻塞)的客户端调用并返回响应结果

4.gRPC的使用场景

补充:架构的演进

1.单体架构

2.垂直架构:将单体架构中的多个模块差分成多个独立项目,形成多个独立的单体架构。

3.分布式架构:在垂直架构的基础上,将公共业务模块抽取出来,作为独立的服务,提供给其他调用者消费,以实现服务的共享与重用。

4.SOA架构(Service-Oriented Architecture,面向服务架构):将应用程序的不同功能单元(服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来。核心部分是ESB(Enterparise Service Bus,企业服务总线),它是服务中介,主要提供服务与服务之间的交互,它的功能包括:负载均衡、流量控制、加密处理、服务监控、异常处理、监控告急等。

5.微服务架构:SOA架构的升华,强调的重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会被拆分为多个可以独立开发、设计、运行的小应用,这些小应用之间通过服务完成交互和集成。

Dubbo可以说是SOA时代的产物,而gRPCSpring Cloud是微服务时代的产物。

根据gRPC的特点,相比DubboSpring CloudgRPC更适合以下场景:

  1. 高性能要求:gRPC采用基于HTTP/2协议的二进制传输格式,具有更高的性能和更好的扩展性,适合对性能要求较高的场景。
  2. 跨语言支持:gRPC支持多种编程语言和平台,可以轻松地实现跨语言的RPC调用,适合多语言环境的场景。
  3. 复杂的数据结构:gRPC使用Protocol Buffers作为标准的接口定义语言(IDL),支持复杂的数据结构和数据类型,适合处理复杂的业务需求。
  4. 网络传输安全:gRPC支持基于TLS的网络传输安全,可以确保数据的安全性,适合对数据安全性要求较高的场景。
  5. 云原生应用:gRPC是云原生应用的重要组成部分,它可以为云原生应用提供高效的服务调用和通信机制,适合云原生应用的场景。

相比DubboSpring CloudgRPC的劣势主要包括以下几点:

  1. 学习成本高:gRPC使用Protocol Buffers作为标准的IDL和数据交换格式,对于开发者来说需要学习新的技术栈,包括Protocol Buffers的语法和使用,以及gRPC框架的使用和配置,学习成本相对较高。

  2. 生态系统相对不成熟:相比于DubboSpring CloudgRPC在国内的生态系统相对较新,社区和开发者数量相对较少,相关的开源项目和工具也相对较少,可能会对开发和部署带来一些不便。

  3. 服务治理能力相对较弱:gRPC的服务治理能力相对于DubboSpring Cloud来说较弱,虽然gRPC提供了基本的负载均衡、服务注册和发现等功能,但是相对于DubboSpring Cloud来说还需要进一步完善。

  4. 不支持动态代理:相比于DubboSpring CloudgRPC不支持动态代理,因此在使用gRPC时需要手动生成客户端和服务端的Stub代码,增加了一定的开发和维护成本。

  5. 不支持RESTful风格:gRPC是一种基于RPC的通信框架,不支持RESTful风格的API设计,相对于DubboSpring Cloud来说,对于一些API设计要求较高的应用场景可能会存在一定的不足。

    gRPC快速入门