您的位置:首页 > 其它

littleRPC学习总结

2020-07-29 18:00 15 查看

LittleRPC源码解析
1.为什么要解析这个框架。
我们要使用RPC完成文件的传输,hession2是通过将数据转化为二进制流的形式进行传输,更加高效,再加上Netty也是比较高效的NIO框架。所以我们使用了这样两种比较高效的形式进行文件的传输。

2.学习代码前需要了解以下知识。
hession2:序列化后通过二进制流的形式传输数据(传输的对象必须实现java.io.Serializable)。
Netty:多路复用 epoll原理。
Zookeeper:注册,发现。
JDK动态代理模式,工厂模式。
RPC过程。
Spring bean加载过程,Spring初始化过程。
RPC:远程方法调用:

1.如何使用:

我们如何通过这个接口传文件?

猜想,我们把这个String替换成FileInputStream对象能不能实现对FileInputStream的序列化和反序列化传输呢?》
FileInputStream有没有实现序列化接口呢?
没有,所以不行。
在翻阅了网络上的资料后,发现将FileInputStream改为byte[],可以实现文件传输功能。
com.taoyuanx.demo.service.MathService#fileDownloadByByte
com.taoyuanx.demo.client.controller.DemoController2#fileDownloadByByte
com.taoyuanx.demo.service.impl.MathServiceImpl#fileDownloadByByte
详情请查考:
https://gitee.com/li_mingxing_admin/MY_Little_RPC

服务方的工作:
初始化Spring容器的时候,要初始化com.taoyuanx.demo.config.DemoConfig中的RpcSpringProviderHandler,新建就相当于初始化,由于它实现ApplicationContextAware这个接口,所以要复写setApplicationContext方法。
com.taoyuanx.littlerpc.server.netty.RpcSpringProviderHandler#setApplicationContext

1.设置Netty常规配置。
com.taoyuanx.littlerpc.server.netty.RpcSpringProviderHandler#init

2.初始化默认协议:HESSIAN2(在init方法中)
3.初始化serviceBean,serviceMap,sericeData对象。
com.taoyuanx.littlerpc.server.RpcProviderHandler#addService

同理:org.springframework.beans.factory.InitializingBean#afterPropertiesSet

开启Netty服务(IP+端口)。

将参数发布到注册中心的过程?(暴露服务过程)
com.taoyuanx.littlerpc.server.RpcProviderHandler#start Netty启动的时候,就从ServiceData中读取配置发布到注册中心,让其管理?
如何在zookeeper注册服务:com.taoyuanx.littlerpc.registry.impl.ZkServiceRegistry#registry

当消费方从zookeeper中获取到配置调用服务接口的时候,服务是如何处理的?
com.taoyuanx.littlerpc.server.netty.NettyServerHandler#channelRead0
channelRead0:NIO多路复用器(epoll): 获取一个可用的channel进行IO操作。
通过servicName获取到serviceMap,然后通过serviceVersion获取到serviceBean.
通过反射执行方法,返回结果(RPCResponce)。

消费方工作:
1.如何触发请求的调用方法?如何管理这个远程类对象的方法?
com.taoyuanx.demo.client.controller.DemoController2#fileDownloadByByte

个人理解:通过动态代理管理对象,当service接口中有方法被调用时会触发并执行java.lang.reflect.InvocationHandler#invoke方法,我们复写这个方法,所以就走自己的逻辑。

2.消费方如何获取到IP,端口,serviceName,version等参数去调用服务方提供的接口呢?
链接zookeeper获取配置。
com.taoyuanx.littlerpc.registry.impl.ZkServiceRegistry#start
com.taoyuanx.littlerpc.registry.impl.ZkServiceRegistry#discovery

3.如何用到Netty发送请求获取结果。
通过工厂模式构建NettyClient对象。
走com.taoyuanx.littlerpc.client.impl.NettyClient#async 通过多路复用器(epoll)找到一个可用的Channel发送请求。

4.如何做到异步发送请求的?
个人理解,构建RpcHolder对象,通过requestId来区分请求,解决异步请求与接收数据的问题。
接收结果io.netty.channel.SimpleChannelInboundHandler#channelRead0,继承并实现方法,让异步请求在有响应结果的时候自动执行。

代码解读:
com.taoyuanx.littlerpc.client.TargetBean#getTarget

每发送一个请求,都会返回一个RPCHolder对象,针对RPCHolder做阻塞,等待响应结果。
阻塞位置:107行async.getRpcResponse
com.taoyuanx.littlerpc.client.RpcHolder#isResp作为是否返回结果的标志位。
RPCHolder使用concurrentHashMap解决多线程并发的线程安全性问题。

至此我关心的源码问题都解决了,如果你有其他的问题,请一起讨论。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: