在前面的文章《Springboot项目中多线程的正确使用方法》中,我们介绍过使用多线程不适合干事务完整性的逻辑,但是可以干一些如下的事情:
写日志 写缓存 等操作
然后我们在这篇文章《Spring Cloud微服务项目模板系列(十)Redisson分布式锁》中介绍了分布式锁的相关知识点。
接下来我们试想一下,在2C领域我们经常会涉及到缓存穿透,缓存雪崩等场景,像这种高并发的场景,我们写缓存这些我们肯定就是需要结合这种多线程加分布式锁来写缓存了,那么整体流程如何呢?我们先画一张图来看看:
上图就是一个大概的完整流程来演示如何通过异步+分布式锁解决redis缓存穿透和缓存雪崩的问题。下面我们详细介绍下整个流程:
1、服务端接收到request请求之后,直接调用DistributeCacheFactory的getvalue方法获取值。 2、DistributeCacheFactory的getvalue方法直接去调用RedisCacheFactory方法的getValue方法获取值。 3、RedisCacheFactory方法的getValue方法首先从根据key从redis中获取值即可,如果获取到的值是json格式,则直接返回。 4、根据key从redis中获取值的值如果不是json格式,则判断是否是空串,如果是空串则直接返回。 5、根据key从redis中获取值的值如果不是空串,那么久启动一个异步线程去执行A任务。 6、A任务的逻辑是,首先根据key用redisson给锁住,如果获取到锁,则查询数据库,并且写入值(json或者空串)到redis中,并且设置expiretime。如果没有获取到分布式锁直接跳过。走第7步骤 7、除了开多线程之外,这里sleep几十毫秒,然后重试下3的RedisCacheFactory方法的getValue方法,获取值。 8、此时RedisCacheFactory方法的getValue方法就能获取到值了,直接return给request。
备注:
1、上诉的DistributeCacheFactory的getvalue方法直接去调用RedisCacheFactory方法的getValue方法获取值主要是由于在高并发的场景里面,除了redis缓存我们可能还有guava本地的一级缓存,二级缓存,他们的interface都是一样的,只是实现不一样,真实的情况下挨个调用实现类即可。
以上步骤的有点事:
1、充分利用异步+分布式锁减少数据可查询频率的问题。 2、充分的扩展了缓存的方式。 3、逻辑清晰明了。 4、对前端的高并发响应没太大影响
下面我们就使用前两篇文章的代码来实现下整个步骤,这里只介绍核心伪代码,具体的伪代码登录后即可下载。
1)首先改造获取值的地方修改为异步
异步的方法里面执行的时候根据这个逻辑去操作即可:
以上就是关于Springboot项目中多线程与分布式锁解决redis缓存穿透缓存雪崩的解决方案,最后按照惯例,附上本案例的源码,登录后即可下载。(登录后有惊喜哦)。
还没有评论,来说两句吧...