当前位置: 首页 > article >正文

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 {
}

�怎么生成对应的代理类,包装成了什么样子的数据
采用的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;
}

只要有这些参数就可以确定服务提供方需要执行的方法,进行执行,
是否关心返回值,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);

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

总结

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


http://www.kler.cn/a/132344.html

相关文章:

  • kvm-dmesg:从宿主机窥探虚拟机内核dmesg日志
  • Redis配置主从架构、集群架构模式 redis主从架构配置 redis主从配置 redis主从架构 redis集群配置
  • python画图|3D errorbars基础教程
  • 【Redis】使用redis实现登录校验功能
  • 5.4.2-1 编写Java程序在HDFS上创建文件
  • 【JavaEE初阶 — 多线程】定时器的应用及模拟实现
  • 从零开始写一个APM监控程序(一)协议
  • 机器学习算法——集成学习
  • java代码的错误
  • Vue理解01
  • 微内核操作系统
  • 【Java 进阶篇】JQuery 遍历 —— 无尽可能性的 `each` 之旅
  • CSS-列表属性篇
  • 世微 降压恒流驱动IC 景观亮化洗墙灯舞台灯汽车灯LED照明 AP5199S
  • 【MATLAB源码-第82期】基于matlab的OFDM系统载波频移偏差(CFO)估计,对比三种不同的方法。
  • 每日一练 | 华为认证真题练习Day132
  • 数据库的基本操作
  • CV计算机视觉每日开源代码Paper with code速览-2023.11.14
  • Linux Traefik工具Dashboard结合内网穿透实现远程访问
  • axios升级依赖版本后报错SyntaxError: Cannot use import statement outside a module
  • Netty传输object并解决粘包拆包问题
  • [Vue 代码模板] Vue3 中使用 Tailwind CSS + NutUI 实现侧边工具栏切换主题
  • 使用vscode的ssh进行远程主机连接
  • CVF_统一多模态之文字生成
  • VUE基础的一些实战总结
  • Linux:systemctl常用命令