rpc与动态代理模型

RPC的英文全称是Remote Procedure Call,翻译为中文叫“远程过程调用”。其中稍显晦涩的其实就是“过程”,过程其实就是方法。所以,可以把RPC理解为“远程方法调用”。

要了解远程过程调用,那先理解过程调用。非常简单,如下图,就是调用一个方法。这太常见了,不多解释。

v2-a5d8d1ec94bc8726faa23902b1507acf_1440w.jpg

而在分布式系统中,因为每个服务的边界都很小,因此很有可能调用别的服务提供的方法。这就出现了服务A调用服务B中方法的需求,这就是远程过程调用。

要想让服务A调用服务B中的方法,最先想到的就是通过HTTP请求。是的,这是很常见的,例如服务B暴露Restful接口,让后让服务A调用它的接口。基于Restful的调用方式因为可读性好(服务B暴露出的是Restful接口,可读性当然好)而且HTTP可以通过各种防火墙,因此非常不错。在18年的(具体报告找不到了,应该是18年)的统计报告中,基于Restful的远程过程调用方式增长很迅猛,大有超过RPC的趋势,不知最近如何了。

然是,基于Restful的远程过程调用也有缺点,即效率比较低。HTTP请求工作在应用层,封装比较复杂,可用信息量低,这是为可读性做的牺牲。可是,服务A调用服务B的过程是应用间的内部过程,牺牲可读性提升效率是可取的。基于这种思路,RPC产生了。

通常,RPC要求在调用方中放置被调用的方法的接口。调用方只要调用了这些接口,就相当于调用了被调用方的实际的方法。于是,调用方可以像调用内部接口一样,调用远程的方法。

v2-f6c29c414d2924b157ec555c6a664343_1440w.jpg

那要想实现这个过程该怎么办呢?别急,咱们一步一步来。

首先,调用方调用的是接口,必须得为接口构造一个假的实现。显然,要使用动态代理。这样,调用方的调用就被动态代理接收到了。

第二,动态代理接收到调用后,应该想办法调用远程的实际实现。这包括下面几步:

识别具体要调用的远程方法的IP、端口

将调用方法的入参进行序列化

通过通信将请求发送到远程的方法中

这样,远程的服务就接收到了调用方的请求。它应该:

反序列化各个调用参数

定位到实际要调用的方法,然后输入参数,执行方法

按照调用的路径返回调用的结果

整个过程如下所示。

v2-bd07238f5104a05889a0f242ef8e33f0_1440w.jpg

这样,RPC操作就完成了。

调用方调用内部的一个方法,但是被RPC框架偷梁换柱为远程的一个方法。之间的通信数据可读性不需要好,只需要RPC框架能读懂即可,因此效率更高。通常使用UDP或者TCP作为通讯协议。

讲到这里,RPC的产生原因、原理应该清楚了。为了让大家真的明白,我写了一个真的是最最简单的RPC实现。把它放到了:

https://github.com/yeecode/EasyRPC github.com

它包含一个客户端,一个服务端。客户端只要调用自身内部的接口,就通过这个小的RPC实现调用到了服务端的方法。

下面是客户端的代码,看着类有点多,其实代码不长。其中的RPC代码完成完成动态代理、远程调用参数序列化、远程调用发起、远程调用结果反序列化的工作。

v2-2bcd46610d7fbc08883047c5c77d6166_1440w.jpg

RPC客户端

下面是服务端的代码,代码更少,完成远程调用接收、调用参数反序列化、调用实际触发、调用结果序列化的工作。

v2-1caa6254ad5961f216a2bc89004c2a7d_1440w.jpg

RPC服务端

这样,一个RPC小框架就做完了,并不复杂。

所以,不要被RPC吓到,它就是让一个应用调用另一个应用中方法的一种实现方式

https://www.zhihu.com/question/25536695

猜你喜欢

转载自www.cnblogs.com/feng9exe/p/12556256.html