当前位置: 首页 > news >正文

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

背景

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

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

问题

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

应用缓存刷新

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

demo:

@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*/@Overridepublic 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());//在进行处理spiloaders.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*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}

相关文章:

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

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

洞悉安全现状,建设网络安全防护新体系

一、“网络攻防演练行动“介绍 国家在2016年发布《网络安全法》&#xff0c;出台网络安全攻防演练相关规定&#xff1a;关键信息基础设施的运营者应“制定网络安全事件应急预案&#xff0c;并定期进行演练”。同年“实战化网络攻防演练行动”成为惯例。由公安部牵头&#xff0…...

spring中怎么通过静态工厂和动态工厂获取对象以及怎么通过 FactoryBean 获取对象

&#x1f600;前言 本章是spring基于XML 配置bean系类中第4篇讲解spring中怎么通过静态工厂和动态工厂获取对象以及怎么通过 FactoryBean 获取对象 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望…...

三元组表实现矩阵相加(数据结构)

代码&#xff1a; 含注释&#xff0c;供参考 #include <stdio.h> #include <stdlib.h>typedef struct {int row,col,value;//分别为行数&#xff0c;列数&#xff0c;数值 } Triple; typedef struct {int len;//非零数值的个数Triple data[200]; } TSMatrix;void…...

ChinaJoy 2023微星雷鸟17游戏本震撼发布:搭载AMD锐龙9 7945HX首发8499元

ChinaJoy 2023展会中微星笔记本再次给大家带来惊喜&#xff0c;发布了搭载AMD移动端16大核的旗舰游戏本&#xff1a;雷鸟17&#xff0c;更重要的这样一款旗舰性能的游戏本&#xff0c;首发价8499元堪称当今游戏本市场中的“性价比爆款”&#xff01; 本着和玩家一同制霸游戏战场…...

各种运算符

算术运算符 1.双目运算符 */%&#xff1a;从左到右优先级依次降低 一些注意事项&#xff1a; 1若a/b都为整型那么结果也为整型&#xff0c;如果ab其中有一个为实型&#xff0c;结果则为实型 求余运算符注意事项&#xff1a; 1运算对象必须为整数 2运算结果的整数跟左边数字的…...

yolov3-tiny原理解析及代码分析

前言 从去年十一月份开始学习yolo神经网络用于目标识别的硬件实现&#xff0c;到现在已经六个月了。一个硬件工程师&#xff0c;C/C基础都差劲的很&#xff0c;对照着darknet作者的源码和网上东拼西凑的原理讲解&#xff0c;一点一点地摸索。刚开始进度很慢&#xff0c;每天都…...

深入了解Redis-实战篇-短信登录

深入了解Redis-实战篇-短信登录 一、故事背景二、知识点主要构成2.1、短信登录2.1.1、生成随机短信验证码引入maven依赖生成验证码 2.1.2、实现登录校验拦截器2.1.3、基于Redis实现短信登录2.1.3.1、发送验证码时存入Redis2.1.3.2、登录时校验验证码 2.1.4、解决状态登录刷新的…...

Mysql的锁

加锁的目的 对数据加锁是为了解决事务的隔离性问题&#xff0c;让事务之前相互不影响&#xff0c;每个事务进行操作的时候都必须先加上一把锁&#xff0c;防止其他事务同时操作数据。 事务的属性 &#xff08;ACID&#xff09; 原子性 一致性 隔离性 持久性 事务的隔离级别 锁…...

【EI/SCOPUS征稿】2023年算法、图像处理与机器视觉国际学术会议(AIPMV2023)

2023年算法、图像处理与机器视觉国际学术会议&#xff08;AIPMV2023&#xff09; 2023 International Conference on Algorithm, Image Processing and Machine Vision&#xff08;AIPMV2023&#xff09; 2023年算法、图像处理与机器视觉国际学术会议&#xff08;AIPMV2023&am…...

Go语言性能优化建议与pprof性能调优详解——结合博客项目实战

文章目录 性能优化建议Benchmark的使用slice优化预分配内存大内存未释放 map优化字符串处理优化结构体优化atomic包小结 pprof性能调优采集性能数据服务型应用go tool pprof命令项目调优分析修改main.go安装go-wrk命令行交互界面图形化火焰图 性能优化建议 简介&#xff1a; …...

K阶斐波那契数列(数据结构)

代码&#xff1a; 注意k阶斐波那契序列定义&#xff1a;第k和k1项为1&#xff0c;前k - 1项为0&#xff0c;从k项之后每一项都是前k项的和 例如&#xff1a;k2时&#xff0c;斐波那契序列为&#xff1a;0,1,1,2,3,5,8,13... k3时&#xff0c;斐波那契序列为&#xff1a;0,0,…...

【JavaEE】博客系统前后端交互

目录 一、准备工作 二、数据库的表设计 三、封装JDBC数据库操作 1、创建数据表对应的实体类 2、封装增删改查操作 四、前后端交互逻辑的实现 1、博客列表页 1.1、展示博客列表 1.2、博客详情页 1.3、登录页面 1.4、强制要求用户登录&#xff0c;检查用户的登录状态 …...

Redis 简介

文章目录 Redis 简介 Redis 简介 Redis&#xff08;Remote Dictionary Server&#xff09;&#xff0c;远程词典服务器&#xff0c;基于 C/S 架构&#xff0c;是一个基于内存的键值型 NoSQL 数据库&#xff0c;开源&#xff0c;遵守 BSD 协议&#xff0c;Redis 由 C语言 实现。…...

CS162 13-17 虚拟内存

起源 为啥我们需要虚拟内存-----------需求是啥&#xff1f; 可以给程序提供一个统一的视图&#xff0c;比如多个程序运行同一个代码段的话&#xff0c;同一个kernel&#xff0c;就可以直接共享 cpu眼里的虚拟内存 无限内存的假象 设计迭代过程 为啥这样设计&#xff1f; 一…...

接口自动化测试-Jmeter+ant+jenkins实战持续集成(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、下载安装配置J…...

最长连续序列——力扣128

文章目录 题目描述法一 哈希表 题目描述 法一 哈希表 用一个哈希表存储数组中的数&#xff0c;这样查看一个数是否存在即能优化至 O(1) 的时间复杂度 每次在哈希表中检查是否存在 x−1 即能判断是否需要跳过 int longestConsecutive(vector<int>& nums){unordered_s…...

uniapp app端 echarts 设置tooltip的formatter不生效问题以及解决办法

需求一&#xff1a; y轴数据处理不同数据增加不同单位 需求二&#xff1a; 自定义图表悬浮显示的内容 需求一&#xff1a;实现方式 在yAxis里面添加formatter yAxis: [{//y轴显示value的设置axisLabel: {show: true,formatter (value, index) > {var valueif (value > 1…...

Spring入门-技术简介、IOC技术、Bean、DI

前言 Spring是一个开源的项目&#xff0c;并不是单单的一个技术&#xff0c;发展至今已形成一种开发生态圈。也就是说我们可以完全使用Spring技术完成整个项目的构建、设计与开发。Spring是一个基于IOC和AOP的架构多层j2ee系统的架构。 SpringFramework&#xff1a;Spring框架…...

深度学习之反向传播

0 特别说明 0.1 学习视频源于&#xff1a;b站&#xff1a;刘二大人《PyTorch深度学习实践》 0.2 本章内容为自主学习总结内容&#xff0c;若有错误欢迎指正&#xff01; 1 forward&#xff08;前馈运算&#xff09;过程 通过输入相应的x和权重w&#xff08;可能涉及bais偏置…...

网络安全 Day23-mariadb数据库数据管理和备份

mariadb数据库数据管理和备份 1. 管理数据库中的库2. 管理库中的表3. 管理表中的字段(列)4. 管理表中的数据(行)5. 数据库数据备份与恢复 1. 管理数据库中的库 进入指定数据库: use 数据库名字库的增删改查 创建数据库: create database 数据库名字指定字符及创建数据库: CREA…...

Centos7 上安装 redis-dump 和redis-load 命令

一、安装rvm 1、安装GPG keys gpg2 --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDBcurl -sSL http://rvm.io/mpapis.asc | gpg2 --import - curl -sSL http://rvm.io/pkuczynski.asc | g…...

【NLP PyTorch】字符级RNN循环网络模型姓氏对应国家分类(项目详解)

字符级RNN模型姓氏对应国家分类 1 序言1 数据来源与加载1.1 数据来源1.2 数据加载2 数据预处理2.1 单个字符数据处理标准2.2 单词的张量构造3 模型创建4 模型训练5 模型检验6 模型预测7 模型部署1 序言 本文的任务主要来源于PyTorch的官方教程,即给定各国人名的数据集,你需要…...

C++设计模式之责任链设计模式

C责任链设计模式 什么是责任链设计模式 责任链设计模式是一种行为型设计模式&#xff0c;它允许多个处理请求的对象串联起来&#xff0c;形成一个处理请求的链。每个对象都有机会处理请求&#xff0c;如果该对象不能处理请求&#xff0c;则将请求传递给链中的下一个对象。 该…...

《Java-SE-第二十三章》之单例模式

文章目录 单例模式概述饿汉模式懒汉模式单线程版懒汉单例多线程版枚举实现单例 单例模式概述 单例模式是设计模式中的一种,其作用能保证某个类在程序中只存在唯一一份实例,而不会创建多份实例。单例模式具体的实现方式, 分成 “饿汉” 和 “懒汉” 两种.。饿汉模式中的饿不并不…...

如何快速同步第三方平台数据?

全量的数据主要是针对多个系统的历史数据,大概有几千万数据,只需要初始化一次即可。 而增量的数据,是系统后续变更的数据。 这个需求其实不简单,至少有以下难点: 不能直接访问第三方数据库。 不能将历史数据导出到excel中,有泄露数据的风险。 如何快速同步历史数据? 增…...

反射(一)

动态 VS 静态语言 动态语言&#xff1a;运行时&#xff0c;可以改变其结构。 Object-C、C#、JS、PHP、Python JS 就是动态语言。 function f() {var x "var a3; var b5; alert(ab)";eval(x); }静态语言&#xff1a;运行时&#xff0c;结构不可变。 Java、C、C J…...

29.利用fminbnd 求解 最大容积问题(matlab程序)

1.简述 用于求某个给定函数的最小值点。 使用方法是&#xff1a; xfminbnd(func,x1,x2) func是函数句柄&#xff0c;然后x1和x2就是函数的区间&#xff0c;得到的结果就是使func取最小值的x值 当然也可以使用[x,fv]fminbnd(func,x1,x2)的方式&#xff0c;这个时候fv就是函数…...

express学习笔记7 - docker跟mysql篇

安装Docker和Navicat Docker 进官⽹https://docs.docker.com/get-docker/ 选择机型安装即可。 Navicat&#xff08;也可以在网上找个破解版本&#xff09; 进官⽹https://www.navicat.com/en/products/navicat-premium 安装完之后连接新建⼀个数据库连接 然后再⾥⾯新建⼀个数…...

Leetcode(一):数组、链表部分经典题目详解(JavaScript版)

数组、链表部分算法题 一、数组1. 二分查找2. 移除数组元素3. 有序数组的平方4. 长度最小的子数组5. 螺旋矩阵 二、链表1. 删除链表元素2. 设计链表3.反转链表4.两两交换链表中的节点5.删除链表倒数第n个节点6.环形链表 提前声明&#xff1a;本博客内容均为笔者为了方便个人理解…...