0.概述
最近学习了动手设计实现一个简易版本的RPC框架,写篇博客记录一下学习过程,顺便理一下整个流程思路。
工具:JDK8、Maven、Tomcat
项目地址:xRPC
1.系统角色
RPC调用的过程,就是服务调用方去调用远程的服务提供方的方法,得到方法的返回值,整个过程就像是调用本地方法一样,网络调用的过程交给框架去做,用户使用起来是无感的。因此,这里面的角色可以大致分为服务调用者、服务提供者、rpc框架,本项目对应的模块分别是Consumer、Provider、CoreRPC。
2.提供服务
将提供的服务方法抽象出来,以接口的形式放在Provider-Common中,具体的实现交给服务真实提供者Provider去实现,也就是各个实现类ServiceImpl。
然后添加一个启动类,将可供调用的方法注册到注册中心去,再启动一个tomcat服务器httpserver监听客户端的服务请求。
3.服务调用
调用者通过动态代理的方式拿到目标服务类的代理对象,调用相应的方法会通过反射进入invoke方法中,通过httpclient去发送请求信息来执行相应的方法,并得到返回结果。
4.RPC核心框架
我们根据一次rpc调用过程来梳理:
1. 调用者获取相应方法的代理对象,自己写一个getProxy()方法,通过Java反射包中的newProxyInstance()方法拿到代理对象,重写invoke()方法,具体逻辑在invoke方法中实现
2. 调用者通过httpclient中的send方法发送请求信息,这些信息中包含请求的接口名称、调用的方法名、参数类型和参数值,这些信息被封装到一个Invocation类中发送给rpc框架
httpserver收到请求后,在httpServerHandler中去处理,反序列化得到请求invocation对象,也就得到了调用的接口名、方法名、参数类型和值,就可以通过反射方式调用真正的方法,并将结果返回
3. 添砖加瓦:一个RPC框架实现RPC调用是最基本的功能,除此之外,还可以实现服务的注册中心功能,将服务提供者的具体地址注册到注册中心去,调用者直接在注册中心根据接口名和方法名去消费服务,若同一个服务是由集群提供的,还可以通过负载均衡来进行服务发现,将可用的服务地址返回给服务消费者。还可以实现服务容错和服务重试等功能,还可以根据用户选择来自定义网络请求工具,本项目采用的是tomcat进行http请求的发送,真正生产实践中RPC请求是高度定制化的,企业会去自定义RPC协议,如消息头、消息体等,实现比HTTP更轻量化更高效的网络传输。
关于注册中心,为了简单学习原理,我采用了Map模拟本地注册,文件共享方式模拟远程注册中心,实际上可以采用Nacos、Redis、ZooKeeper等更先进的注册中心去实现,后续有空可以更加完善一下。