RPC:Remote Procedure Call Protocol,指的是远程过程调用协议,一般使用在分布式业务或者微服务架构风格中。
即一个节点通过网络调用的方式来请求另一个节点提供的服务的过程,也可以简单的理解为client访问server上提供的函数(像调用本地函数一样,去调用一个远端服务)。
在RPC框架中主要有三个角色:Provider、Consumer和Registry。如下图所示:
节点角色说明,这边看起来,跟其他的服务注册与发现框架原理差不多(如 Eureka、Consul):
Service(provider): 暴露服务的服务提供方。
Client(consumer): 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
RPC(Remote Procedure Call)远程过程调用,即一个节点通过网络调用的方式来请求另一个节点提供的服务的过程,也可以简单的理解为client访问server上提供的函数。
他的基本调用流程如下:
上面是一次完整的RPC调用流程(这边指的是同步调用情况下),步骤顺序如下:
RPC的目标是要把2、3、4、7、8、9这些步骤都封装起来。
无论是何种类型的数据,最终都需要转换成二进制流在网络上进行传输,数据的发送方需要将对象转换为二进制流,而数据的接收方则需要把二进制流再恢复为对象。
理解对服务的调用和RPC模式的结果返回,注意箭头的指向的区别。
1、动态代理(Spring中重点了解下)
生成 client stub和server stub需要用到 Java 动态代理技术 ,我们可以使用JDK原生的动态代理机制,可以使用一些开源字节码工具框架 如:CgLib、Javassist等。
2、序列化
序列化:将Java对象转换成byte[]的过程,也就是编码的过程;
反序列化:将byte[]转换成Java对象的过程;
3、NIO
当前很多RPC框架都直接基于netty这一IO通信框架,比如阿里巴巴的HSF、dubbo,Hadoop Avro,推荐使用 Netty 作为底层通信框架。
4、服务注册中心
可选技术:Redis 、Zookeeper,
一般的RPC框架会接入注册中心来进行注册与发现的管理,比如Dubb与Zookeeper 的完美结合。
所以实现RPC调用过程,结构分为三部分:client、grpc、server。
虽然RPC可以简单的理解为client 去调用server 中的函数。但是RPC通信和直接的函数调用还是有很大的区别的:
内容项 | RPC调用 | 本地调用 |
函数寻址 | IP端口路由(NamingService + LoadBalancer)+函数路由 | 内存指针 |
传递数据 | 序列化后的数据流 | 内存对象 |
调用方异常处理 | timeout、retry、curcuit breaker | 抛出Exception / 函数返回固定异常标识的数据 |
被调用方异常处理 | 认证鉴权、过载保护 | 入参检查 / 执行异常捕获和处理 |
问题定位 | 分布式Trace、监控、日志中心 | 日志记录 / 断点调试跟踪 |
性能优化 | 连接池、多路复用、线程池、轻量级线程、non-block IO 等 | 编译器优化(inline等) |
这里可以看出rpc比函数调用复杂的多,比如:
正因为有如此的复杂性,所以我们需要一个RPC框架来处理这些复杂的事情,让RPC看起来就像本地调用一样简单。
实现的过程:
有些RPC框架不只是处理通信相关的工作(如数据的序列化和反序列化,协议的解析/打包,数据的压缩解压缩,数据的加密和解密),还可以做很多微服务治理的工作。
比如Dubbo支持对服务的治理,包括 服务注册与发现、故障注入、超时重试、负载均衡、连接管理和健康检查等。除此之外,服务端还有认证鉴权、并发流量限制、函数路由、协议适配和参数校验等等复杂的策略。
所以一个成熟的RPC框架也可以是一个非常复杂全面的分布式系统,在一定程度上协助工程进行微服务建设。
对比项 | Dubbo | gRPC | brpc | Thrift |
公司 | Ali | Baidu | ||
通讯协议 | tcp/http | http2 | 多种协议 | tcp/http |
序列化协议 | 可扩展 | protobuf | protobuf/json/mcpack | 可扩展 |
开发语言 | Java | 跨语言 | C++ / Java | 跨语言 |
主要特点 | 服务治理、扩展性 | 跨语言、性能 | 高性能、扩展性 | 跨语言 |
github star | 36.9K | 33.5K | 12.9K | 8.9K |
RPC 主要用于公司内部的服务调用,性能消耗低,传输效率高,实现复杂。
HTTP 主要用于对外的异构环境,浏览器接口调用,App 接口调用,第三方接口调用等。
RPC 使用场景(大型的网站,内部子系统较多、接口非常多的情况下适合使用 RPC):
通过本篇我们详细学习了RPC的概念和原理,以及它能够提供的能力。也对目前业内主流的RPC的框架有了一定的了解。后面一篇我们以Dobbo为例子,来学习下怎么使用RPC框架来进行服务之间的通信。