怎么在springboot中自定义两级缓存(springboot,编程语言)

时间:2024-05-04 12:40:13 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

    %E6%80%8E%E4%B9%88%E5%9C%A8springboot%E4%B8%AD%E8%87%AA%E5%AE%9A%E4%B9%89%E4%B8%A4%E7%BA%A7%E7%BC%93%E5%AD%98

如上两个注解和spring中缓存的注解基本一致,只是去掉了一些不常用的属性。说到这里,不知道有没有朋友注意过,当你在springboot中单独使用redis缓存的时候,Cacheable和CacheEvict注解的value属性,实际上在redis中变成了一个zset类型的值的key,而且这个zset里面还是空的,比如@Cacheable(value="cache1",key="key1"),正常情况下redis中应该是出现cache1 -> map(key1,value1)这种形式,其中cache1作为缓存名称,map作为缓存的值,key作为map里的键,可以有效的隔离不同的缓存名称下的缓存。但是实际上redis里确是cache1 -> 空(zset)和key1 -> value1,两个独立的键值对,试验得知不同的缓存名称下的缓存完全是共用的,如果有感兴趣的朋友可以去试验下,也就是说这个value属性实际上是个摆设,键的唯一性只由key属性保证。我只能认为这是spring的缓存实现的bug,或者是特意这么设计的,(如果有知道啥原因的欢迎指点)。

回到正题,有了注解还需要有个注解处理类,这里我使用aop的切面来进行拦截处理,原生的实现其实也大同小异。切面处理类如下:

上面这个界面使用了一个cacheEnable变量控制是否使用缓存,为了实现无缝的接入springboot,必然需要受到原生@EnableCaching注解的控制,这里我使用一个spring容器加载完成的监听器,然后在监听器里找到是否有被@EnableCaching注解修饰的类,如果有就从spring容器拿到MultiCacheAspect对象,然后将cacheEnable设置成true。这样就可以实现无缝接入springboot,不知道朋友们还有没有更加优雅的方法呢?欢迎交流!监听器类如下

实现了无缝接入,还需要考虑多点部署的时候,多点的ehcache怎么和redis缓存保持一致的问题。在正常应用中,一般redis适合长时间的集中式缓存,ehcache适合短时间的本地缓存,假设现在有A,B和C服务器,A和B部署了业务服务,C部署了redis服务。当请求进来,前端入口不管是用LVS或者nginx等负载软件,请求都会转发到某一个具体服务器,假设转发到了A服务器,修改了某个内容,而这个内容在redis和ehcache中都有,这时候,A服务器的ehcache缓存,和C服务器的redis不管控制缓存失效也好,删除也好,都比较容易,但是这时候B服务器的ehcache怎么控制失效或者删除呢?一般比较常用的方式就是使用发布订阅模式,当需要删除缓存的时候在一个固定的通道发布一个消息,然后每个业务服务器订阅这个通道,收到消息后删除或者过期本地的ehcache缓存(最好是使用过期,但是redis目前只支持对key的过期操作,没办法操作key下的map里的成员的过期,如果非要强求用过期,可以自己加时间戳自己实现,不过用删除出问题的几率也很小,毕竟加缓存的都是读多写少的应用,这里为了方便都是直接删除缓存)。总结起来流程就是更新某条数据,先删除redis中对应的缓存,然后发布一个缓存失效的消息在redis的某个通道中,本地的业务服务去订阅这个通道的消息,当业务服务收到这个消息后去删除本地对应的ehcache缓存,redis的各种配置如下

消息发布类如下:

具体操作缓存的类如下:

工具类如下

具体使用缓存,和之前一样只需要关注@Cacheable和@CacheEvict注解,同样也支持spring的el表达式。而且这里的value属性表示的缓存名称也没有上面说的那个问题,完全可以用value隔离不同的缓存,例子如下

附上主要的依赖包

"org.springframework.boot:spring-boot-starter-redis:1.4.2.RELEASE",

'net.sf.ehcache:ehcache:2.10.4',

"org.json:json:20160810"

本文:怎么在springboot中自定义两级缓存的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Java使用for循环解决经典的鸡兔同笼问题示例下一篇:

4 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18