• RPC实现简单解析


    RPC是什么,先摘取一段解释:
    RPC全称为远程过程调用(Remote Procedure Call),它是一种计算机通信协议,允许一个计算机程序调用另一个计算机上的子程序,而无需了解底层网络细节。通过RPC,一个计算机程序可以像调用本地程序一样调用远程程序,使得分布式应用程序的开发更加简单和高效。

    根据对应的接口定义去找到对应实际提供服务的方法去调用,需要的必要信息,要调用的服务的地址,要调用的类,方法,方法参数类型,参数值,怎么接收返回值,多个服务提供者的话需要负载均衡
    RPC 框架很多,找一个比较纯粹的框架来分析下是怎么实现的,自己实现的话,也可以照葫芦画瓢,有哪些是必要的,当然同样的效果可以有不同的实现,自己也可以针对一些特性进行替换。

    xxl-rpc实现原理解析

    怎么对外提供服务,考虑到性能原因,采用的netty来实现的服务
    要调用的地址,这里可以直接指定,可以通过本地或者注册中心获取到提供的服务列表进行负载
    类,方法,方法参数类型,参数值,为什么需要这些,因为这些才可以唯一确定一个调用的方法,具体是调用的哪个
    返回值,是否需要关心返回值,是否需要异步,异步的话是通过回调还是future,怎么进行实现的

    xxl-rpc对于代理的生成

    针对需要依赖的接口生成对应代理的,代理是什么时候生成的,这里还是先看spring环境中的情况吧
    通过spring的生命周期管理,实现了InstantiationAwareBeanPostProcessor来对对象初始化之后对对象的属性进行处理,看是不是有依赖rpc的接口,有依赖的对其进行属性注入对应生成的代理类

    public class XxlRpcSpringInvokerFactory implements InitializingBean, DisposableBean, BeanFactoryAware, InstantiationAwareBeanPostProcessor {
    }
    
    • 1
    • 2

    �怎么生成对应的代理类,包装成了什么样子的数据
    采用的JDK的动态代理,有对应的版本号区分,然后类名,方法,方法参数类型,参数值,地址可以支持负载,那么要传递给提供服务方的数据是什么样子呢,就是这样子的

    public class XxlRpcRequest implements Serializable{
    	private static final long serialVersionUID = 42L;
    	
    	private String requestId;
    	private long createMillisTime;
    	private String accessToken;
    
        private String className;
        private String methodName;
        private Class<?>[] parameterTypes;
        private Object[] parameters;
    
    	private String version;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    只要有这些参数就可以确定服务提供方需要执行的方法,进行执行,
    是否关心返回值,xxl-rpc提供了四种选择,同步调用,异步调用返回future,异步设置callback,oneway不关心返回值
    底层实现这几种的方式,首先oneway不关心返回值,不需要多考虑,rpc内部都是直接异步发送,那么怎么接受返回值呢,采用的回调的方法,就是clent自己也起一个服务,然后当服务端执行完成之后,进行远程调用回来结果,怎么确定是哪次调用的呢,上面封装参数的requestId就派上用场了,采用uuid生成的方式,唯一标志,回调之后有等待结果的,就对其进行唤醒,需要执行回调方法的就进行执行回调

    具体实现上,通过XxlRpcFutureResponse 来封装返回值,里面记录了request,然后根据requestId,把对应的resonse进行存放到一个公共集合,这里用的一个concurrentHashMap里面,然后回调的时候从里面通过对应的requestId取对应的resposne对象,把返回值记录上,状态修改,

    XxlRpcInvokeFuture invokeFuture = new XxlRpcInvokeFuture(futureResponse);
    // future存入到了threadLocal里面
    XxlRpcInvokeFuture.setFuture(invokeFuture);
    
    • 1
    • 2
    • 3

    �返回的对象也通过工具类直接放到对应的ThreadLocal里面,可以获取到对应的futureResponse,然后可以get等待返回状态的改变,未返回的时候加锁等待,等返回之后通过唤醒锁,可以设置超时时间,这样一个基础的rpc功能就齐了

    总结

    提供服务可以采用netty或者别的也可以,然后服务暴露就需要自己完成去暴露了,这里没主动去解析,主要考虑的调用端,调用时候根据对应的注解,去生成代理对象进行注入,地址可以提供负载,然后进行调用,返回值通过回调的方式,回调之后通过改变对应的对象的状态,对其进行唤醒,就可以取到对应的返回值,一次rpc调用完成

  • 相关阅读:
    JSON.parse 和 JSON.stringify 详解
    ChatGPT AIGC自动生成多条件复杂计算函数
    set() 函数 | Python
    .Net添加了引用,仍然提示找不到命名空间
    集群启动详解
    .Net Core&RabbitMQ消息存储可靠机制
    编译安装LAMP架构搭建wordpress个人博客和discuz论坛——编译安装基于 FASTCGI 模式LAMP架构多虚拟主机WEB应用
    计算机组成原理之定点除法
    【c++百日刷题计划】 ———— DAY12,奋战百天,带你熟练掌握基本算法
    leetcode 58
  • 原文地址:https://blog.csdn.net/weixin_39808420/article/details/134426875