RPC实现简单解析

RPC是什么,先摘取一段解释:

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

根据对应的接口定义去找到对应实际提供服务的方法去调用,需要的必要信息,要调用的服务的地址,要调用的类,方法,方法参数类型,参数值,怎么接收返回值,多个服务提供者的话需要负载均衡

RPC 框架很多,找一个比较纯粹的框架来分析下是怎么实现的,自己实现的话,也可以照葫芦画瓢,有哪些是必要的,当然同样的效果可以有不同的实现,自己也可以针对一些特性进行替换。

xxl-rpc实现原理解析

怎么对外提供服务,考虑到性能原因,采用的netty来实现的服务

要调用的地址,这里可以直接指定,可以通过本地或者注册中心获取到提供的服务列表进行负载

类,方法,方法参数类型,参数值,为什么需要这些,因为这些才可以唯一确定一个调用的方法,具体是调用的哪个

返回值,是否需要关心返回值,是否需要异步,异步的话是通过回调还是future,怎么进行实现的

xxl-rpc对于代理的生成

针对需要依赖的接口生成对应代理的,代理是什么时候生成的,这里还是先看spring环境中的情况吧

通过spring的生命周期管理,实现了InstantiationAwareBeanPostProcessor来对对象初始化之后对对象的属性进行处理,看是不是有依赖rpc的接口,有依赖的对其进行属性注入对应生成的代理类

java 复制代码
public class XxlRpcSpringInvokerFactory implements InitializingBean, DisposableBean, BeanFactoryAware, InstantiationAwareBeanPostProcessor {
}

�怎么生成对应的代理类,包装成了什么样子的数据

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

java 复制代码
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对象,把返回值记录上,状态修改,

java 复制代码
XxlRpcInvokeFuture invokeFuture = new XxlRpcInvokeFuture(futureResponse);
// future存入到了threadLocal里面
XxlRpcInvokeFuture.setFuture(invokeFuture);

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

总结

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

相关推荐
麻瓜也要学魔法3 小时前
链路状态路由协议-OSPF
网络
Estar.Lee3 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
傻啦嘿哟4 小时前
代理IP在后端开发中的应用与后端工程师的角色
网络·网络协议·tcp/ip
Red Red4 小时前
网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
网络·笔记·学习·安全·web安全
向阳12184 小时前
Dubbo HTTP接入之triple协议
网络协议·http·dubbo
亚远景aspice6 小时前
ISO 21434标准:汽车网络安全管理的利与弊
网络·web安全·汽车
草莓base6 小时前
【手写一个spring】spring源码的简单实现--bean对象的创建
java·spring·rpc
Estar.Lee6 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
友友马6 小时前
『 Linux 』网络层 - IP协议(一)
linux·网络·tcp/ip