远程过程调用失败_远程过程调用(RPC)是怎么实现的?

1 RPC简介

RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。

2 RPC实现

RPC的实现中一个重要的功能就是动态代理。整个过程如下:

首先,对于用户方而言:

  • 只提供接口不提供实现类,所有的接口文件都导出后,调用方放在一个专门目录下
  • 接口千奇百怪,但是都没有具体实现
  • 代理要代理掉专门目录下的所有接口,任何对这里接口的调用都被序列化后转到远端

假设,我们有一个接口如下:

b33fab4b4c55394f7f2e760db3e43a12.png

只有方法名称,也不知道接口在远端的实现类的名称。

然后,我们的ProxyHandler如下:

721b858c1ec75e7bf308a3043c9e5d5f.png

具体使用时这样:

16d8349dc6a5bed8291e3484f28776fe.png

这样,就可以实现RPC的代理了。运行结果:

57a0ed3b7b1a038ea09784e2f1dbab45.png

那具体实现RPC可如下。

  • 首先如代码所示,我们只需要接口,不需要知道任何实现类的信息就可以创建一个接口的代理实现。就和生成RemoteService remoteService一样。
  • 因为所有的接口都在指定目录下,我们可以扫描该目录下的所有接口,批量生成所有接口的实例,并把生成的bean都放入spring中管理。这样,用户就可以用autowair注入所有实现。而实际上我们的代理proxy就成了所有接口的实现。
  • 用户调用任何接口时,都调用了我们生成的bean实现。其实都进入了我们相同的handler实现,实现中我们可以知道用户想要调用的完整方法名称(从它的目录路径可以分析出目标应用名)、参数。然后序列化后去远端调用并返回结果即可。

3 动态代理

cglib是通过字节码,生成了目标类的子类实现动态代理的。因此,对于final的方法无法使用cglib进行动态代理。

首先引入Cglib包:

77b50cdcf4b0749829b7d31041a59ded.png

首先,目标对象不发生任何变化,并且该类也不需要实现任何接口了:

78e3b087498162282a25a3c1d1f2df11.png

代理类写法如下:

92c3b2c3a2afb70e9d1b3e2404eb1ede.png

通过代码我们也可以看出,代理类是作为目标类的子类出现的,在调用目标类方法时,实际是调用父类。

使用如下:

ff0acb4a59b3cd55c60632c418aa8ec8.png

使用过程比较简单:

1. 生成一个代理对象

2. 告诉代理对象,它的实现在哪里

3. 告诉代理对象,它的父类是谁

4. 生成代理类的对象

5. 调用代理对象的方法

这样,对生成的代理对象进行调用时,会调用到它的回调对象,然后回调对象中根据操作可能调用目标对象(父类)的方法。

得到结果:

before speak

hello Jack

after speak

OK


欢迎关注我们,不错过每期的原创干货。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值