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
大多数的计算机通信协议都基于TCP
或UDP
协议生成,它们是计算机网络中最常用的两种传输层协议,可以提供不同的数据传输方式以满足不同的应用需求。
TCP
的三个特点是面向连接、可靠、基于字节流(顺便一提,UDP
的三个特点是无连接、不可靠、面向数据报),但使用纯裸TCP
容易出现粘包问题等,需要在它的基础上加入一些自定义规则用于区分消息边界。例如常见的可以将消息包装成消息头+消息体的形式:
这其中消息头可以包含多种信息,例如完整的包长度、消息体是否被压缩过、消息体格式等等,只要通信体系的上下游均约定好特定的消息头,就可以实现互认,这也就是所谓的协议。也正是由此,基于TCP
衍生出众多协议,其中就包含多种RPC
协议。
准确来说,RPC
(远程过程调用,Remote Procedure Call
)本身并不是一个具体的协议,而是一种调用方式,它可以帮助我们调用远程计算机上某个服务的方法,使得调用远程方法与调用本地方法一样简单。举例而言,如果有两个不同的服务A
、B
,它们分别部署在不同的机器上,此时若要在服务A
中调用服务B
中的某个方法,就可以使用RPC
。
RPC
的原理图如下:
我们可以将整个框架看作五个主要部分:
1.客户端(服务消费端,client
):调用远程方法的一段。
2.客户端桩(client stub
):其实就是一个代理类,可以把客户端调用的方法、类、方法参数等信息传递到服务端。
3.网络传输:可以把客户端调用的方法信息等各种参数传输到服务端,服务端执行完后再把结果传输回客户端。网络传输的实现方式有很多,例如Socket
、Netty
(推荐)等。
4.服务端桩(server stub
):这里并不是代理类,服务端桩实际指的是接收到客户端执行方法的请求后,去执行对应的方法然后返回结果给客户端的类。
5.服务端(服务提供端,server
):提供远程方法的一段。
整个RPC
执行的流程如下:
1.客户端以本地调用的方式调用远程远程服务。
2.客户端桩接收到调用指令后将方法、参数等组装成能够进行网络传输的消息体(序列化):RpcRequest
。
3.客户端桩找到远端服务的地址,并利用网络传输将消息发送到服务提供段。
4.服务端桩接收到消息后将消息反序列化为Java
对象:RpcRequest
。
5.服务端桩根据RpcRequest
中的类、方法、方法参数等信息调用本地的方法。
6.服务端桩得到方法执行结果并将其组装成能够进行网络传输的消息体:RpcResponse
(序列化)发送至客户端。
7.客户端桩接收到消息并将消息反序列化为Java
对象:RpcResponse
,得到最终的结果并发送给客户端。
有不少框架的实现都基于RPC
调用方式:常见的比如Dubbo
、Thrift
、Motan
、gRPC
等。
注意:
1.RPC
并不是协议,而是一种调用方式,RPC
的具体实现比如Dubbo
、gRPC
等框架才是协议。
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 Buffers
的IDL
语言来定义服务接口和数据类型,并使用底层协议来实现跨语言的RPC
通信。gRPC
基于HTTP/2
标准设计,带来注入双向流、流控、头部压缩、单TCP
连接上的多复用请求等特性,这使得它在移动设备上表现的更好,更节省电与空间占用。
概括下来,gRPC
主要包括以下特点:
1.高性能:gRPC
使用基于HTTP/2
的二进制编码协议,可以提供更高的传输效率和可靠性。
2.跨语言支持:gPRC
支持多种语言,包括C++
、Java
、Python
、Go
、Kotlin
、PHP
、Node.js
、C#
等。
3.强类型IDL
:gRPC
使用Protocol Buffers
作为IDL
语言,可以定义服务接口和数据类型,并生成对应的代码,可以简化开发者的工作。
4.流式处理:gRPC
支持流式处理,可以实现服务器端流式和客户端流式,适用于大数据量的场景。
5.安全性:gPRC
支持TLS/SSL
加密协议,可以保证数据的安全性和完整性。
由于gRPC
是一种PRC
框架,因此它的具体运行流程也与RPC
框架类似:
定义一个服务端,指定其能够被远程调用的方法(包括参数和返回类型)。在服务端实现这个接口,并运行一个gRPC
服务器(gRPC Server
)来处理客户端的调用,在客户端中有一个gPRC
桩(gRPC Stub
)提供与服务器相同的方法。
gRPC
客户端和服务端可以在多种环境中运行和交互,并且可以使用任何gRPC
支持的语言编写。你可以选择用Java
编写gRPC
服务端,同时可以用Go
、Python
等其他语言创建客户端。此外,Google
最新的API
也包含了gRPC
版本的接口,可以让使用者较为容易的将Google
的功能集成入应用中。
gRPC
采用名为协议缓冲区(Protocol Buffers
,可以简称为ProtoBuf
)的开放源代码技术,提供极为高效且不受平台影响的序列化格式,用于序列化服务相互发送的结构化消息。它与XML
和JSON
类似,是一种更加灵活高效的数据格式,可以用于通讯协议、数据存储等领域,基本支持所有主流编程语言且与平台无关,在一些高性能且对响应速度有要求的数据传输场景非常使用。
ProtoBuf
在gRPC
框架中可以起到的作用有:定义数据结构、定义服务接口、通过序列化与反序列化方式提升传输效率。
在使用XML
、JSON
进行数据编译时,数据文本格式更容易阅读,但进行数据交换时,设备就需要耗费大量的CPU
在I/O
操作上,这样会影响整个传输效率。但ProtoBuf
不同于它们,它会将字符串进行序列化后再进行传输,即二进制数据。
可以看出二者的内容差异并不大,但是ProtoBuf
的编码内容只是提供给操作者阅读的,实际传输的并不是以这种文本形式,而是序列化后的二进制数据,字节数会比JSON
于XML
的字节数少的多,速率更快。
与采用文本格式的JSON
相比,采用二进制格式的ProtoBuf
在速度上可以达到前者的5倍。
基于ProtoBuf
,可以得到gRPC
开发的核心:.proto
文件,它定义了gRPC
服务和消息的约定。根据这个文件,gRPC
框架可以生成服务基类,消息以及完整的客户端代码。
通过在服务端于客户端之间共享.proto
文件,可以从端到端生成消息和客户端代码。生成客户端代码可以消除客户端和服务器上的重复消息,并为用户创建一个强类型的客户端,这样可以在具有较多服务和应用程序中节省大量开发时间。
gRPC大致的请求流程如下:
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
时代的产物,而gRPC
、Spring Cloud
是微服务时代的产物。
根据gRPC
的特点,相比Dubbo
与Spring Cloud
,gRPC
更适合以下场景:
- 高性能要求:
gRPC
采用基于HTTP/2
协议的二进制传输格式,具有更高的性能和更好的扩展性,适合对性能要求较高的场景。 - 跨语言支持:
gRPC
支持多种编程语言和平台,可以轻松地实现跨语言的RPC
调用,适合多语言环境的场景。 - 复杂的数据结构:
gRPC
使用Protocol Buffers
作为标准的接口定义语言(IDL
),支持复杂的数据结构和数据类型,适合处理复杂的业务需求。 - 网络传输安全:
gRPC
支持基于TLS
的网络传输安全,可以确保数据的安全性,适合对数据安全性要求较高的场景。 - 云原生应用:
gRPC
是云原生应用的重要组成部分,它可以为云原生应用提供高效的服务调用和通信机制,适合云原生应用的场景。
相比Dubbo
与Spring Cloud
,gRPC
的劣势主要包括以下几点:
-
学习成本高:
gRPC
使用Protocol Buffers
作为标准的IDL
和数据交换格式,对于开发者来说需要学习新的技术栈,包括Protocol Buffers
的语法和使用,以及gRPC
框架的使用和配置,学习成本相对较高。 -
生态系统相对不成熟:相比于
Dubbo
和Spring Cloud
,gRPC
在国内的生态系统相对较新,社区和开发者数量相对较少,相关的开源项目和工具也相对较少,可能会对开发和部署带来一些不便。 -
服务治理能力相对较弱:
gRPC
的服务治理能力相对于Dubbo
和Spring Cloud
来说较弱,虽然gRPC
提供了基本的负载均衡、服务注册和发现等功能,但是相对于Dubbo
和Spring Cloud
来说还需要进一步完善。 -
不支持动态代理:相比于
Dubbo
和Spring Cloud
,gRPC
不支持动态代理,因此在使用gRPC
时需要手动生成客户端和服务端的Stub
代码,增加了一定的开发和维护成本。 -
不支持
RESTful
风格:gRPC
是一种基于RPC
的通信框架,不支持RESTful
风格的API
设计,相对于Dubbo
和Spring Cloud
来说,对于一些API
设计要求较高的应用场景可能会存在一定的不足。