RPC 工作原理

  1. RPC 异步与 I/O 的异步
  2. 总结

RPC 的全称是 Remote Procedure Call,它是一种进程间通信方式。允许像调用本地服务一样调用远程服务,它的具体实现方式可以不同,例如 Spring 的 HTTP Invoker,Facebook 的 Thrift 二进制私有协议通信。

RPC 框架的目标就是让远程过程(服务)调用更加简单、透明,RPC 框架负责屏蔽底层的传输方式(TCP 或者 UDP)、序列化方式(XML/Json/ 二进制)和通信细节。框架使用者只需要了解谁在什么位置提供了什么样的远程服务接口即可,开发者不需要关心底层通信细节和调用过程。

PC 框架实现的几个核心技术点总结如下:

远程服务提供者需要以某种形式提供服务调用相关的信息,包括但不限于服务接口定义、数据结构,或者中间态的服务定义文件,例如 Thrift 的 IDL 文件,WS-RPC 的 WSDL 文件定义,甚至也可以是服务端的接口说明文档;服务调用者需要通过一定的途径获取远程服务调用相关信息,例如服务端接口定义 Jar 包导入,获取服务端 IDL 文件等。

远程代理对象:服务调用者调用的服务实际是远程服务的本地代理,对于 Java 语言,它的实现就是 JDK 的动态代理,通过动态代理的拦截机制,将本地调用封装成远程服务调用。

通信:RPC 框架与具体的协议无关,例如 Spring 的远程调用支持 HTTP Invoke、RMI Invoke,MessagePack 使用的是私有的二进制压缩协议。

序列化:远程通信,需要将对象转换成二进制码流进行网络传输,不同的序列化框架,支持的数据类型、数据包大小、异常类型以及性能等都不同。不同的 RPC 框架应用场景不同,因此技术选择也会存在很大差异。一些做的比较好的 RPC 框架,可以支持多种序列化方式,有的甚至支持用户自定义序列化框架(Hadoop Avro)。

RPC 异步与 I/O 的异步

RPC 异步与 I/O 的异步没有必然关系,当然,在大多数场景下,RPC 框架底层会使用异步 I/O,实现全栈异步。

RPC 框架异步调度模型如下所示:

异步 RPC 调用的关键点有 2 个:

不能阻塞调用方线程:接口调用通常会返回 Future 或者 Promise 对象,代表异步操作的一个回调对象,当异步操作完成之后,由 I/O 线程回调业务注册的 Listener,继续执行业务逻辑。

请求和响应的上下文关联:除了 HTTP/1.X 协议,大部分二进制协议的 TCP 链路都是多路复用的,请求和响应消息的发送和接收顺序是无序的。所以,异步 RPC 调用需要缓存请求和响应的上下文关联关系,以及响应需要使用到的消息上下文。

正如上图所示,当 RPC 调用请求消息发送到 I/O 线程的消息队列之后,业务线程就可以返回,至于 I/O 线程采用同步还是异步的方式读写消息,与 RPC 调用的同步和异步没必然的关联关系,当然,采用异步 I/O, 整体性能和可靠性会更好一些,所以现在大部分的 RPC 框架底层采用的都是异步 / 非阻塞 I/O。以 Netty 为例,无论 RPC 调用是同步还是异步,只要调用消息发送接口,Netty 都会将发送请求封装成 Task,加入到 I/O 线程的消息队列中统一处理,相关代码如下所示:

异步回调的一些实现策略:

Future/Promise:比较常用的有 JDK8 之前的 Future,通过添加 Listener 来做异步回调,JDK8 之后通常使用 CompletableFuture,它支持各种复杂的异步处理策略,例如自定义线程池、多个异步操作的编排、有返回值和无返回值异步、多个异步操作的级联操作等。

线程池 +RxJava: 最经典的实现就是 Netflix 开源的 Hystrix 框架,使用 HystrixCommand(创建线程池)做一层异步封装,将同步调用封装成异步调用,利用 RxJava API,通过订阅的方式对结果做异步处理,它的工作原理如下所示:

总结

通过以上分析可以得出如下结论:

RPC 异步指的是业务线程发起 RPC 调用之后,不用同步等待服务端返回应答,而是立即返回,当接收到响应之后,回调执行业务的后续逻辑。

I/O 的异步是通信层的具体实现策略,使用异步 I/O 会带来性能和可靠性提升,但是与 RPC 调用是同步还是异步没必然关系。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wshten@gmail.com

文章标题:RPC 工作原理

本文作者:KevinTen

发布时间:2019-09-15, 00:00:00

最后更新:2019-09-15, 17:47:34

原始链接:http://github.com/kevinten10/2019/09/15/Rpc/Rpc-核心技术/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

csdn zhihu github