关于单体架构缓存刷新实现方案

这篇具有很好参考价值的文章主要介绍了关于单体架构缓存刷新实现方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

如果各位看官是分布式项目应该都采用分布式缓存了,例如redis等,分布式缓存不在本次讨论范围哈;我个人建议是,如果是用户量比较大,建议采用分布式缓存机制,后期可以很容易前后到分布式服务或微服务。

我这边项目基本上都是单体架构,因为业务场景需要,用户一般就几十个,最多,最多也就是100多用户,所以,单体是完全满足的,同时用户对于系统的要求也不高,因此采用了单体架构,但是后期可以切换到分布式,这是后期需求,如果遇到在调整。

问题

ok,背景介绍完。那就是说下单体的问题出现的情况;由于业务场景需要,很多的应用缓存和功能局部缓存,一开始设计这块时,就没好好设计这块,现在遇到问题了;第一个,应用缓存比较乱(也有公共的缓存机制,但是有些业务不希望放到公共缓存里,一般就在当前类上定义了缓存),第二个线上也出现了几次因为缓存未及时刷新,造成垃圾数据的产生,因此,在这些问题的出现后,需要进一步设计缓存机制了,在不大调整业务代码的前提下如何及时进行刷新应用缓存呢?

应用缓存刷新

一开始刷新机制很简单,有模糊匹配缓存key进行删除,有指定key进行删除的,但是总有写业务写的不太规范,有些乱,关键后期也不晓得,在什么情况下进行刷新了缓存,这样的操作将会给后期项目遗留问题;怎么解决呢?方案是创建缓存接口,需要进行实现接口,然后需要进行缓存刷新的,实现该接口进行处理,什么时间进行刷新呢,根据业务,进行通知即可;现在面临着一个问题,有些类是交给spring管理的,有些类是项目自己管理的并没有交给spring,这个问题如何解决呢?也好解决,第一种,全部交给spring容器管理,通过spring拿到所有刷新缓存接口实现类,进行循环调用刷新接口,这块属于一刀切,不过比较简单,我这边没有采用;第二种是原有代码不调整,之前什么样就是什么样,那就要有spi机制,这块可以采用谷歌服务发现方式,这里还需要考虑一个问题,如果交给spring就不用spi发现,没有交给spring就需要进行发现,但是为了防止重复,优先使用sping机制进行获取所偶刷新解决的实现类,然后通过spi找到所有实现的类,进行排查把增量的实现类添加给缓存类进行统一循环处理即可

demo:文章来源地址https://www.toymoban.com/news/detail-615143.html

@Service
@Slf4j
public class RefreshCacheUtils implements ApplicationContextAware, ApplicationRunner {

    private final static List<RefreshCache> REFRESH_CACHE_LIST = new ArrayList<>();

    private ApplicationContext applicationContext;

    
    public static void refreshByDeviceId(String deviceId) {
        for (RefreshCache refreshCache : REFRESH_CACHE_LIST) {
            refreshCache.refreshByDeviceId(deviceId);
        }
    }

    
    public static void refreshByBusinessId(String businessId) {
        for (RefreshCache refreshCache : REFRESH_CACHE_LIST) {
            refreshCache.refreshByBusinessId(businessId);
        }
    }

    
    public static void refreshdDefaultExecution(String otherParameter) {
        for (RefreshCache refreshCache : REFRESH_CACHE_LIST) {
            refreshCache.defaultExecution(otherParameter);
        }
    }

    /**
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        Map<String, RefreshCache> beans = applicationContext.getBeansOfType(RefreshCache.class);

        //使用jdk提供的类ServiceLoader来加载RefreshCache的子类
        //如果服务发现没有,请检查RefreshCache实现类是否添加注解:@AutoService(value = RefreshCache.class)
        //如果实现了RefreshCache的对应的类是被spring管理,就不用加@AutoService(value = RefreshCache.class),这块逻辑已经进行整合了
        ServiceLoader<RefreshCache> loaders = ServiceLoader.load(RefreshCache.class);
        //把spring容器里的Cache实现类直接放入缓存
        REFRESH_CACHE_LIST.addAll(beans.values());
        //在进行处理spi
        loaders.stream().forEach(s -> {
            //是否已经存在spring容器进行打标记
            AtomicBoolean isExistFlag = new AtomicBoolean(false);

            for (RefreshCache refreshCache : REFRESH_CACHE_LIST) {
                String name = refreshCache.getClass().getName();
                String spiName = s.get().getClass().getName();
                //判断spi的对象是否在spring容器里,如果在直接打上标记为true并结束循环
                if (name.equals(spiName) || name.contains(spiName + "$$")) {
                    isExistFlag.set(true);
                    break;
                }
            }
            //判断标记是否为true,如果为true就说明都不处理,如果为false,加入到刷新缓存列表
            if (!isExistFlag.get()) {
                REFRESH_CACHE_LIST.add(s.get());
            }
        });

        log.info("所有待刷新缓存对象信息初始化完成:{}", REFRESH_CACHE_LIST);

    }

    /**
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

到了这里,关于关于单体架构缓存刷新实现方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Java架构师缓存通用设计方案

    Java架构师缓存通用设计方案

    想学习架构师构建流程请跳转:Java架构师系统架构设计 在实际应用中需要考虑的实际问题。首先,前端页面可以做缓存,虽然图上没有显示,但在现实应用中这是提高性能的一个重要方面。前端页面缓存可以将静态内容

    2024年02月07日
    浏览(13)
  • Redis缓存设计与性能优化【缓存和数据库不一致问题,解决方案:1.加过期时间这样可以一段时间后自动刷新 2.分布式的读写锁】

    Redis缓存设计与性能优化【缓存和数据库不一致问题,解决方案:1.加过期时间这样可以一段时间后自动刷新 2.分布式的读写锁】

    在大并发下,同时操作数据库与缓存会存在数据不一致性问题 1、双写不一致情况 2、读写并发不一致 解决方案: 1、对于并发几率很小的数据(如个人维度的订单数据、用户数据等),这种几乎不用考虑这个问题,很少会发生缓存不一致, 可以给缓存数据加上过期时间,每隔一

    2024年04月13日
    浏览(18)
  • 【技术解决方案】(多级)缓存架构最佳实践

    【技术解决方案】(多级)缓存架构最佳实践

    凌晨三点半了,太困了,还差一些,明天补上… 因为自己最近做的项目涉及到了缓存,所以水一篇缓存相关的文章,供大家作为参考,若发现文章有纰漏,希望大家多指正。 缓存涉及到的范围颇广,从CPU缓存,到进程内缓存,到进程外缓存。再加上已经凌晨一点了,我得保

    2024年02月07日
    浏览(12)
  • vue项目关于iframe嵌套的页面,在切换tab标签时会被重新刷新的问题处理方案

    这两天工作中遇到一个这样的需求,切换tab标签时,要求对应的tab页面不刷新,但是项目中加入了一部分含有iframe的页面,在切换路由的过程中,如果使用keep-alive是达不到缓存ifram嵌套的页面效果的。 vue中的keep-alive 1.原理:vue 的缓存机制并 不是直接存储 DOM 结构 ,而是将

    2024年02月04日
    浏览(24)
  • 转载 spring @Cacheable扩展实现缓存自动过期时间以及自动刷新

    转载 spring @Cacheable扩展实现缓存自动过期时间以及自动刷新

    用过spring cache的朋友应该会知道,Spring Cache默认是不支持在@Cacheable上添加过期时间的,虽然可以通过配置缓存容器时统一指定。形如 复制 但有时候我们会更习惯通过注解指定过期时间。今天我们就来聊一下如何扩展@Cacheable实现缓存自动过期以及缓存即将到期自动刷新 2 实现

    2024年02月03日
    浏览(5)
  • 【案例实战】高并发业务的多级缓存架构一致性解决方案

    【案例实战】高并发业务的多级缓存架构一致性解决方案

    我们在高并发的项目中基本上都离不开缓存,那么既然引入缓存,那就会有一个缓存与数据库数据一致性的问题。 首先,我们先来看看高并发项目里面Redis常见的三种缓存读写模式。 Cache Aside 优点 读取效率高,缓存命中率高,写操作与数据库同步,数据一致性较高,实现较

    2024年02月13日
    浏览(13)
  • 用Selenium操作网页,如何在打开网站的过程中,实现刷新,清除缓存的效果

    在使用 Selenium 操作网页时,可以通过控制浏览器选项来实现刷新和清除缓存的效果。下面是使用 Python 和 Selenium 的示例代码: 刷新网页: 清除缓存: 在上述代码中,我们首先创建了一个浏览器对象,并打开了一个网站。然后,通过 refresh() 方法刷新页面,或者通过禁用缓存

    2024年01月24日
    浏览(13)
  • 深入浅出 -- 系统架构之单体架构

    深入浅出 -- 系统架构之单体架构

    单体架构(Monolithic Architecture)是一种传统的软件架构模式,将整个应用程序作为一个单一的、统一的单元进行开发、部署和扩展。在单体架构中,所有的功能模块都被打包在一起,共享同一个代码库和数据库。 例如,在网上商城系统中,JavaWeb工程通常会被打成WA R包部署在

    2024年04月10日
    浏览(15)
  • springboot 集成caffeine单体缓存两种方式及算法简介 (注解/手动)

           Caffeine 是基于 JAVA 8 的高性能缓存库。并且在 spring5 (springboot 2.x) 后,spring 官方放弃了 Guava,而使用了性能更优秀的 Caffeine 作为默认缓存组件。        Caffeine 因为使用了  Window-TinyLFU  缓存淘汰策略,提供了一个 近乎最佳的命中率 。综合了 LRU 和 LFU 算法的长处,

    2024年02月03日
    浏览(11)
  • 微服务OR单体架构

    说到微服务OR单体架构,其实这两个场景并不存在很明确的争议界限的,而是可以理解为一个项目或者说一个系统的不同阶段。比如说系统初始阶段采用单体架构,待用户量、数据量上来之后采用微服务架构,这都是很正常的架构现象。那么为什么会出现争议呢? 对于这个问

    2024年04月25日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包