JavaGuide-RPC框架项目学习笔记-未完待续

本笔记为JavaGuide哥RPC项目的学习笔记,感谢Guide哥的无私奉献!

  1. RPC,Remote Procedure Call,远程过程(方法)调用,本地上某个服务的方法要调用远程主机上某个服务的方法。

  2. RPC的原理。简单讲主要涉及三个问题:如何告知远程主机需调用的目标方法是哪个?(在两边同时维护一个<函数名,ID>映射表)将本地的参数传输给远程主机时,要将其转变为适合传输的字节流(序列化,反序列化)。使用什么协议传输?(TCP、UDP,HTTP)

  3. 首先,根据作者的教程以及POM文件查看项目依赖关系。

  4. 由于对mave不熟悉,即使理清了依赖关系,对应打了jar包,编译时也报了错。后来发现是因为没有将包install到本地仓库,导致不可见。(关键词:maven生命周期

  5. SocketRpcClient/Server,serviceDiscovery/Registry,核心类:ExtensionLoader(),扩展加载器(写法上参照了dubbo,而dubbo的写法,个人感觉似乎与JDK的ClassLoader有点像)。维护加载器缓存(类级),以及扩展实例缓存(类级、对象级),扩展类型缓存(对象级)。

    通过对应加载器,获取扩展实例时,先从“本地的”对象级缓存中找。若未命中,获取扩展类型,以之为Key从“全局的”类级实例缓存中找,命中则更新本地缓存。若仍未命中,则反射创建扩展实例并更新类级、对象级实例缓存。

    获取扩展类型是通过“本地的”对象级扩展类型缓存获取,若未命中则解析本地配置文件,加载类型并更新缓存。

  6. dubbo网站应用演进,dubbo架构及特点。

  7. 单例模式,DCL,指令重排,volatile(内部类、枚举)。

  8. ConcurrentMap,get取值后判空用putIfAbsent而非put是为了DCL?

  9. ExtensionLoader()的实现里用到了Holder类,该类将对象包裹,并提供一个volatile限定的引用(我看了下,ExtensionLoader不可变,成员均final修饰,故无法volatile限定,意思是可以加一层间接实现 final+volatile 共存?)。

  10. volatile的一揽子破事。

  11. 行吧,进度有点慢,考虑到该项目迭代至今扩展了很多功能,如果一直纠结于细节,对于RPC的主旨部分很难快速了解。故在调研一番后,打算从该带佬发布的第一个正式版开始看,提纲挈领。

  12. client使用动态代理的原因:

    1. 相同的模式:对于每种方法,进行RPC时我们都要做同样的事情:将相关信息打包序列化发送给服务端,接受服务端回信反序列化相关结果。故我们需要实现一个类做这些事情,但目前还不一定要用代理的方式。
    2. 未知的方法:我们希望像调用本地方法那样调用远程方法,因此要求那个类必须提供对应的方法。我们可以通过继承同一接口的方式实现方法的统一(这也是JDK动态代理的要求,只能代理实现接口实现类),但这个接口信息,要等到运行时才能确定,故我们必须用动态代理的方式。
  13. lombok @Builder 建造者模式。实现方法,设置内部类作为中间对象传参,另:通过返回this可以实现method的链式调用。

  14. RPC时要传送方法的名称参数类型,以便通过反射匹配获取对应方法对象-Method。获取Method后,调用invoke即可实现方法调用(若方法有参数,此时传入,此外,这说明在客户端还需传送方法的实参)。

  15. Java序列化通过ObjectOutputStream、ObjectInputStream的writeObject、readObject。序列化对象类需要继承Serializable标记接口。此外,为了避免序列化后,类发生改动产生的版本不一致问题,编译器为Serializable实现类自动添加serialVersionUID属性,当反序列化时,若检测到serialVersionUI与本地类的一致,则报错。serialVersionUID可手动添加,当进行兼容性升级时,不要改动serialVersionUID;反之则修改。

  16. ver1.1改动:

    1. 为RpcRequest增加serialVersionUID;
    2. 服务端:增加异常消息枚举类、调用回执RpcResponse类
    3. 客户端:RpcClient增加对RpcResponse的相应分析。
  17. IDEA可以用git方便的查看每个文件的每个历史改动…不用自己在网页上慢慢点了…orz…太强了…

  18. ver1.2改动:

    1. 服务端:将服务注册功能抽离成接口ServiceRegistry,以及实现类DefaultServiceRegistry(synchronized方法同步,服务多接口重复注册对象)。导致线程类不再直接获取服务对象,而是通过注册中心间接获取
  19. ver2.0改动:

    1. 客户端:RpcClient类抽出RpcClient接口,与RpcClientProxy解耦,原实现类改名为SocketRpcClient。
    2. 服务端:RpcRequestHandler与ServiceRegistry的初始化,从RpcServer推迟到线程类SocketRpcRequestHandlerRunnable,懒加载,线程池职责更明确单一。
    3. 增加对netty与kryo的支持
  20. Netty:基于NIO的客户端-服务器框架,可以简化网络通信编程。

  21. interface Constant> extends Comparable这个通配符在这里有意义吗?。。。

  22. ThreadLocal(kryo并发不安全)。

参考资料:

  1. Idea操作Maven超级详细使用 基础篇。
  2. Idea操作Maven超级详细使用 高级篇。
  3. MAVEN01_概述+核心概念+IDEA中如何使用(创建项目)。
  4. MAVEN02_依赖范围+依赖冲突+解决冲突+继承聚合。

你可能感兴趣的:(JAVA,java,rpc,笔记)