RPC框架(网上资料整理)

参考:深入浅出 RPC - 深入篇
参考:RPC入门总结(一)RPC定义和原理

1.概念

RPC 的全称是 Remote Procedure Call,是一种进程间通信方式。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的,本质上编写的调用代码基本相同。

2.为什么使用RPC

1.RPC要解决的两个问题

  1. 解决分布式系统中,服务之间的调用问题。
  2. 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。

2.使用长连接

通过心跳方式保持长连接,不必每次通信都要像http一样去3次握手什么的,减少了网络开销

3.注册中心

有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。

4.安全性

安全机制一般和RPC的具体实现有关。HTTP也是一种RPC,它的加密传输一般是基于TLS的,也就是常见的HTTPS。整个过程大致是先通过非对称密钥传递对称密钥,然后用对称密钥加密HTTP消息。但在可信环境中更多只要阻止未授权的误访问就行了:因为加密是有明显性能损耗的。这时候通过非对称密钥认证下身份就行了,这一般是连接级的操作,在长连接中开销很小。

5.解耦

rcp只关心调用方和被调用方的进程通信,不需要关心具体业务。

3.RPC 调用分类

RPC 调用分以下两种:

  • 同步调用
    客户方等待调用执行完成并返回结果。
  • 异步调用
    客户方调用后不用等待执行结果返回,但依然可以通过回调通知等方式获取返回结果。
    若客户方不关心调用返回结果,则变成单向异步调用,单向调用不用返回结果。

4.组件分类

1. RpcServer

负责导出(export)远程接口

2. RpcClient

负责导入(import)远程接口的代理实现

3. RpcProxy

远程接口的代理实现

4. RpcInvoker

客户方实现:负责编码调用信息和发送调用请求到服务方并等待调用结果返回
服务方实现:负责调用服务端接口的具体实现并返回调用结果

5. RpcProtocol

负责协议编/解码

6. RpcConnector

负责维持客户方和服务方的连接通道和发送数据到服务方

7. RpcAcceptor

负责接收客户方请求并返回请求结果

8. RpcProcessor

负责在服务方控制调用过程,包括管理调用线程池、超时时间等

9. RpcChannel

数据传输通道

5.架构分解

在这里插入图片描述

在这里插入图片描述

6.RPC框架的核心技术点

1.服务暴露

远程提供者需要以某种形式提供服务调用相关的信息,包括但不限于服务接口定义、数据结构、或者中间态的服务定义文件。
目前,大部分跨语言平台 RPC 框架采用根据 IDL 定义通过 code generator 去生成 stub 代码,这种方式下实际导入的过程就是通过代码生成器在编译期完成的。代码生成的方式对跨语言平台 RPC 框架而言是必然的选择,而对于同一语言平台的 RPC 则可以通过共享接口定义来实现。这里的导入方式本质也是一种代码生成技术,只不过是在运行时生成,比静态编译期的代码生成看起来更简洁些。

2.远程代理对象

服务调用者用的服务实际是远程服务的本地代理。说白了就是通过动态代理来实现。
java 里至少提供了两种技术来提供动态代码生成,一种是 jdk 动态代理,另外一种是字节码生成。

3.通信

RPC框架与具体的协议无关。RPC 可基于 HTTP 或 TCP 协议,Web Service 就是基于 HTTP 协议的 RPC,它具有良好的跨平台性,但其性能却不如基于 TCP 协议的 RPC。

4.多连接

单连接和多连接最大的区别在于,每个连接都有自己私有的发送和接收缓冲区,因此大数据量传输时分散在不同的连接缓冲区会得到更好的吞吐效率。

5.心跳

连接是由 client 端发起建立并维持。如果 client 和 server 之间是直连的,那么连接一般不会中断(当然物理链路故障除外)。如果 client 和 server 连接经过一些负载中转设备,有可能连接一段时间不活跃时会被这些中间设备中断。为了保持连接有必要定时为每个连接发送心跳数据以维持连接不中断。心跳消息是 RPC 框架库使用的内部消息,在协议头结构中也有一个专门的心跳位,就是用来标记心跳消息的,它对业务应用透明。

6.序列化\编码内容

序列化可以采用现有流行的序列化框架.
出于效率考虑,编码的信息越少越好(传输数据少),编码的规则越简单越好(执行效率高)

7.Rpc异常处理

正是这些区别决定了使用 RPC 时需要更多考量。当调用远程接口抛出异常时,异常可能是一个业务异常,也可能是 RPC 框架抛出的运行时异常(如:网络中断等)。业务异常表明服务方已经执行了调用,可能因为某些原因导致未能正常执行,而 RPC 运行时异常则有可能服务方根本没有执行,对调用方而言的异常处理策略自然需要区分。

8.总结

由于 RPC 固有的消耗相对本地调用高出几个数量级,本地调用的固有消耗是纳秒级,而 RPC 的固有消耗是在毫秒级。那么对于过于轻量的计算任务就并不合适导出远程接口由独立的进程提供服务,只有花在计算任务上时间远远高于 RPC 的固有消耗才值得导出为远程接口提供服务。

发布了82 篇原创文章 · 获赞 15 · 访问量 3130

猜你喜欢

转载自blog.csdn.net/qq_34326321/article/details/103473449