【rpc】RPC理解与实现

rpc远程过程调用(Remote Procedure Call)的缩写形式。不同于本地调用,函数与函数之间同属于同一块内存空间,如需调用某个函数,只需要找到所在内存地址即可。远程调用,通俗地说,便是有两台服务器 A,B,一个应用部署在 A 服务器上,想要调用 B 服务器上应用提供的函数/方法,需要通过网络来表达调用的语义和传达调用的数据。

应用:分布式框架dubbo等。

本地通过定义一个接口,动态代理一个请求返回的远程服务对象。

三个要点:Call ID映射、序列化与反序列化、网络传输。
RPC调用过程:
1、客户端通过调用本地服务的方式调用服务
2、客户端将方法、入参等信息序列化后,找到服务端的远程服务地址,将消息通过网络发送给服务端
3、服务端收到消息进行解码(反序列化
4、服务端调用本地服务进行相关处理,将执行结果序列化后发送给客户端
5、客户端解码反序列化获取最后结果

使用技术:

  • 动态代理
    客户端使用动态代理代理服务端的服务对象,对消费方的请求进行处理。
  • 序列化与反序列化
    为了使参数对象可以在网络中传输,需要用到序列化技术。常见的序列化方式有 JDK 自带序列化(Serializable 接口),HESSIAN 序列化,Kryo 序列化等。
  • NIO
    为了支持高并发,确保客户端与服务端的可靠通信,一般会使用到NIO技术,常用Netty作为网络应用框架实现。
  • 服务注册中心
    为了便于客户端找到远程服务的地址,使用类似Zookeeper这种注册中心提供服务端注册服务,并支持分布式部署集群。

参考文档
https://www.jianshu.com/p/29d75a25eeaf
https://www.jianshu.com/p/78f72ccf0377
具体实现
https://my.oschina.net/huangyong/blog/361751

tips of 动态代理

动态代理与事务的冲突:在一个Service内部,事务方法之间的嵌套调用,普通方法和事务方法之间的嵌套调用,都不会开启新的事务。
动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!(触发的是代理类实例的方法,而非原对象的方法)

代理模式:使用代理对象来完成对另一对象方法、接口的调用,然后可以在此基础上增加自定义逻辑。
动态代理:https://www.cnblogs.com/gonjan-blog/p/6685611.html

创建一个InvocationHandler对象
    InvocationHandler\<interfaceA>
interfaceA指一个接口,为了动态代理该接口的所有实现类

动态创建一个代理对象

Proxy.newProxyInstance(xx.class.getClassLoader(), new Class<?>[]{xxx.class}, invocationHandler);