手写 RPC 框架 笔记
RPC项目 笔记总结篇
本次提交的是2-4期的笔记
大家好,我是影子,目前已经是我二刷RPC项目了,在跑通所有业务流程后,我准备将教程重新进行学习,并在借鉴原有教程的基础上,用自己的话,重新整理一份学习笔记。
正所谓,当一个知识点,能够自己说出来并且让别人明白,这才算是真正的学会~(费曼学习法)
下面简单分享一下2-4期的收获,详细内容以pdf文件分享
第二期 全局配置
技术收获:
-
结合Huttol工具类实现了ConfigUtils,用于读取application.properties的文件内容
-
通过分析业务流程需要的数据,编写配置类的属性,例如: 注册中心地址 | 服务接口 | 序列化方式 | 网络通信协议等等
第三期 Mock接口开发
技术收获:
-
进一步实践动态代理与代理工厂的实践
-
实践通过配置属性来控制Mock功能的启动与关闭
具体流程 我画了一个简单的图例,只是简单的一个理解,如果有误还请大家指正!
第四期 自定义序列化器与SPI机制
技术收获:
-
实践了四种序列化器 JDK | JSON | Hessian | Kryo的自定义方式,同时将代码保留,便于下次直接使用,😄
-
学习了SPI机制的知识,这里重点理解SPI机制含义:让服务提供者通过特定文件将实现注册到系统中,后续使用反射的方式进行调用,实现了解耦合,或许这就已经是一个面试题,当然,要结合项目实践来讲是最好
-
实践工厂 单例模式,并手写了一遍双检锁。
具体流程 我画了一个简单的图例,只是简单的一个理解,如果有误还请大家指正!
最后,整个项目做下来后,对我而言收获更大的是对于需求分析和设计方案 流程图绘制这方面的能力加强,建议大家至少阅读两遍教程,会发现每次读都收获不一样。
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
又又又又又完结,本来是点赞系统之前就在写rpc,点赞系统出来后就搁置了,现在终于完结
4
求助一下,未初始化的List为什么值是[]而不是null,做RPC项目时遇到一个很奇怪的问题,在做注册中心本地缓存时,服务缓存private List serviceCache;没有做任何初始化,但第一次执行readCache方法时,serviceCache的值不是null,而是[],自己排查过程:1,类没有使用@Data注解2,成员变量私有,唯一对外提供修改的方法为writeCache3,在方法
3
myrpc 学习笔记-008 重试机制
4
myrpc 学习笔记-009 容错机制
4
myrpc 学习笔记-0010 启动机制和注解驱动(完结)
5
作者分享
终于拿到鱼厂周边啦!
记录一下😃
18
面试题 | 02 | 非面经,纯分享,辩证看待答案。
#面试题#
压力山大的问题:
可以讲下API签名认证的流程吗?
(感觉这种流程题,如果是线下面试,是不是拿出纸,画出流程图给面试官看更好些)
找工作的我:
好的,那其实签名认证的话,它主要是为了保证接口的安全性,防止一些需要成本的,例如使用到AI的API的这种的,万一被攻击,会导致资源被大量消耗。
那API签名认证的话,它涉及到五个参数,首先两个是accessKey和secretKey,它们类似于公钥和密钥,那这个的信息的话,只能让对应的用户看到。
第三个参数的话是sign,标签,我在项目中是采用实现一个工具类去制作的,是用的secretKey 、请求参数和签名算法(MD5)然后生成一个sign1,然后客户端会把这个accessKey 和请求参数一起发送到服务端,那服务端会根据accessKey去数据库查询这个secretKey,接着还是利用刚才提到的工具类去生成sign2,最后比较sign1和sign2是否相同,相同,则说明请求参数没有被篡改。
那其实一般到这里就算基本的流程了,但是为了防止被攻击重放,还需要第四个参数,nonce,我们会在每次请求中生成一个随机的nonce,将这个nonce存入redis中,并设置好TTL,那么往后的请求过来的时候,跟redis中的nonce进行比较,如果一样的话则拒绝请求,如果不存在,才放行请求,那这样的话就可以解决重放的问题。
但是如果说这个攻击者它等到redis中的nonce过期后再进行重放,那它又可以请求成功。对于这种情况,就得使用到第五个参数,timestamp时间戳,假设我们定义的时间戳是一分钟,那服务器只能接收一分钟内的时差请求,那我们在redis设置的nonce的TTL略大于一分钟即可。这样请求重放过来,如果在一分钟内的,因为nonce存在,无法放行。如果请求大于一分钟的,因为超过了一分钟时差的规定,也无法放行。至此,API签名认证所有流程就算完毕了。
13
面试题打卡 | 01
#面试题# 分享
大家好,我是影子。
最近在准备面试题的东西,之前也不断的了解过八股的记忆方式。
个人感觉比较好的方法如下:
1. 通过先了解原理或者答案,同时实践一遍,正所谓好记性不如烂笔头,实践一遍的时候,对于很多细节也能把控住。
2. 对于一个问题,不要仅限于表面,当问题问到A的时候,试想自己是面试官的话,接下来会怎么问这个问题相关的,而不是,对于一个问题,背完就结束,那么稍微问深一点九接不住了。
3. 也是我个人比较喜欢的。 对于多个相关的问题,学习后,整理为一整篇答案,因为很多问题,其实还是可以联系起来的,后面就是通过上下联系的方式,将全部梳理出来,类似于跟别人讲解,当自己能讲出来的时候,这个题,百分之80已经掌握了,剩下的就是偶尔多看看,加深记忆。
本次,以Redis的问题作为分享,因为基本都是自己的口语化方式,模拟跟面试官的对话,当然,如果是大厂的深度拷问,肯定不够用,纯属打卡分享,哪里有误还望大家指出。
压力山大的问题:
redisson实现的分布式锁能解决主从一致性的问题吗?
如果业务非要保证数据的强一致性,这个该怎么解决呢?
能介绍一下redis的分布式锁的相关知识吗?
.....| 自行补充
找工作的我:
好的,因为在分布式的场景下,一个服务被部署到多个服务器上,那么在并发的情况下,可能导致一个任务被多次执行。那像我们在单机使用的锁,例如syscornized lock锁,就没法解决这个问题。那么,就需要使用到分布式锁。
分布式锁的实现有很多方式,例如redis的setnx命令,这个命令是存入一个key value,如果存入成功,则返回一个1。如果已经有这个key了,那么返回0,存入失败,并且结合lua脚本去实现。但是通过这个方式实现会有很多问题。第一个是流程会比较复杂,成本高。第二个是它的不可重入问题,第三个是它的不可重试问题,第四个是它的超时无法自动续期问题,第五个是主从一致问题。
那基于这些问题,我在项目中采用的是redisson。redisson很好的基于redis去解决了很多分布式的问题,例如分布式限流 分布式锁等等。
首先是不可重入的问题,因为它的底层是一个可重入锁,底层的流程是如果有请求过来,先判断是否已经存入线程号,如果没有,则直接获取锁,如果有,那么判断是否是同一个线程号,如果不是,则直接拒绝。如果是,则给redis中的value值加一,然后重置TTL。那么释放锁的话同样的,给value值减一,直到value为0释放锁,让其他的线程去获取锁。
那第二个的话是不可重试问题,我们使用Redisson的时候,可以定义一个时间,当一个线程获取不到锁的时候,让它不断的自旋进行尝试,直到时间到了,才停止尝试获取。
那第三个的话是不可自动续期问题,redisson中有一个看门狗机制,我们可以在代码中将trylock这个方法中将参数设置为-1,则算开启了这个看门狗机制,那这个机制的话,可以保证我们的业务完整执行,不会说因为当TTL结束后,锁就自动释放了,那具体的话我在实践中看到的是,给的时间是默认30秒,当到达三分之二的时间的时候,就会自动续期。直到我们的业务完整的执行完再释放锁。
那最后的话是主从一致的问题。因为我们底层使用的setnx的命令,那当我们获取到锁的时候,它是写入主节点的,但是因为主节点是异步复制到从节点,那如果说此时主节点宕机了,而线程一获取到锁后又没有释放锁,从节点也没有同步信息。 同时,从节点中会选举一个作为主节点。此时线程二来获取锁,则会获取成功,最终导致出现了一把锁两个线程获取,这是不合理的。
那解决的方式的话,我们可以使用mulitlock这个多重锁,使用这个锁的话,必须保证所有节点都成功的写入获取锁的线程信息后,才算获取成功,那这样就避免了因为redis多节点信息不一致导致的多个线程获取同一把锁的情况。
14
手写 RPC 框架 笔记
18
智谱AI-SDK入门实践之Java(保姆级教程)
21

