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

基于Spring Boot的多级缓存系统设计

在构建大规模应用时,缓存系统是提高性能的关键因素之一。为了更有效地利用缓存,我们可以设计一个基于Spring Boot的多级缓存系统,结合本地内存缓存(如Caffeine)和分布式缓存(如Redis)。以下是一个简单的多级缓存系统的设计概要:

1. 选择缓存框架

在Spring Boot中,我们可以选择合适的缓存框架,比如Ehcache、Redis、Caffeine等。可以通过在pom.xml中引入相应的依赖来集成这些框架。

2. 配置缓存

在application.properties或application.yml中配置缓存的相关属性,如缓存类型、大小、过期时间等。

3. 定义缓存管理类

创建一个缓存管理类,用于配置多级缓存,指定各级缓存的顺序和策略。

package com.nbsaas.boot.config;import com.github.benmanes.caffeine.cache.CaffeineSpec;
import com.nbsaas.boot.cache.MultiLevelCacheManager;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@Configuration
@EnableCaching
public class CacheConfig {@Primary@Order(Ordered.HIGHEST_PRECEDENCE)@Beanpublic CacheManager cacheManager(CaffeineCacheManager caffeineCacheManager,RedisCacheManager redisCacheManager) {MultiLevelCacheManager multiLevelCacheManager = new MultiLevelCacheManager();multiLevelCacheManager.addCache(caffeineCacheManager);multiLevelCacheManager.addCache(redisCacheManager);return multiLevelCacheManager;}@Beanpublic CaffeineCacheManager caffeineCacheManager() {// 配置Caffeine缓存CaffeineCacheManager cacheManager = new CaffeineCacheManager("caffeineCache","yourCacheName");cacheManager.setCaffeineSpec(caffeineSpec());return cacheManager;}@Order(Ordered.LOWEST_PRECEDENCE)@Beanpublic RedisCacheManager redisCacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 配置序列化(解决乱码的问题),过期时间600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();return RedisCacheManager.builder(factory).cacheDefaults(config).build();}private CaffeineSpec caffeineSpec() {// 配置Caffeine缓存规格return CaffeineSpec.parse("maximumSize=100");}
}

4. 实现缓存管理器和缓存

实现MultiLevelCacheManager类和MultiLevelCache类,用于管理和协调多个缓存层次。


package com.nbsaas.boot.cache;import org.springframework.cache.Cache;import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.Callable;public class MultiLevelCache implements Cache {private final ArrayList<Cache> caches = new ArrayList<>();public void addCache(Cache cache) {caches.add(cache);}@Overridepublic String getName() {return "multiLevelCache";}@Overridepublic Object getNativeCache() {return this;}@Overridepublic ValueWrapper get(Object key) {for (Cache cache : caches) {ValueWrapper wrapper = cache.get(key);if (wrapper != null) {return wrapper;}}return null;}@Overridepublic <T> T get(Object key, Class<T> type) {ValueWrapper wrapper = get(key);return (wrapper != null) ? (T) wrapper.get() : null;}@Overridepublic <T> T get(Object key, Callable<T> valueLoader) {ValueWrapper wrapper = get(key);T obj= (wrapper != null) ? (T) wrapper.get() : null;return obj;}@Overridepublic void put(Object key, Object value) {for (Cache cache : caches) {cache.put(key, value);}}@Overridepublic ValueWrapper putIfAbsent(Object key, Object value) {ValueWrapper wrapper = get(key);if (wrapper == null) {put(key, value);return null;}return wrapper;}@Overridepublic void evict(Object key) {for (Cache cache : caches) {cache.evict(key);}}@Overridepublic boolean evictIfPresent(Object key) {return Cache.super.evictIfPresent(key);}@Overridepublic void clear() {for (Cache cache : caches) {cache.clear();}}@Overridepublic boolean invalidate() {boolean result=true;for (Cache cache : caches) {result= cache.invalidate();}return result;}
}

package com.nbsaas.boot.cache;import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;import java.util.ArrayList;
import java.util.Collection;public class MultiLevelCacheManager implements CacheManager {private final ArrayList<CacheManager> cacheManagers = new ArrayList<>();public static final int REDIS_CACHE_EXPIRATION = 600; // Redis缓存过期时间(秒)public void addCache(CacheManager cacheManager) {cacheManagers.add(cacheManager);}@Overridepublic Cache getCache(String name) {MultiLevelCache multiLevelCache = new MultiLevelCache();for (CacheManager cacheManager : cacheManagers) {Cache cache = cacheManager.getCache(name);if (cache != null) {multiLevelCache.addCache(cache);}}return multiLevelCache;}@Overridepublic Collection<String> getCacheNames() {Collection<String> cacheNames = new ArrayList<>();for (CacheManager cacheManager : cacheManagers) {cacheNames.addAll(cacheManager.getCacheNames());}return cacheNames;}
}

5. 使用缓存

在Service层或方法上使用@Cacheable、@CachePut、@CacheEvict等注解来标记需要缓存的方法。

@Service
public class MyService {@Cacheable(value = "caffeineCache", key = "#id")public String getCachedData(String id) {// 查询数据库或其他业务逻辑return "Cached Data for " + id;}
}

通过以上步骤,我们成功建立了一个基于Spring Boot的多级缓存系统。这个设计支持在本地内存和分布式缓存之间实现多级缓存,从而更好地满足不同场景下的性能需求。在实际应用中,可以根据具体需求调整缓存的层次和配置,以达到最佳性能和资源利用率。

相关文章:

基于Spring Boot的多级缓存系统设计

在构建大规模应用时&#xff0c;缓存系统是提高性能的关键因素之一。为了更有效地利用缓存&#xff0c;我们可以设计一个基于Spring Boot的多级缓存系统&#xff0c;结合本地内存缓存&#xff08;如Caffeine&#xff09;和分布式缓存&#xff08;如Redis&#xff09;。以下是一…...

k8s-配置与存储-配置管理

文章目录 一、配置存储1.1 ConfigMap1.1.1.基于文件夹的创建方式1.1.2指定文件的创建方式1.1.3 配置文件创建configmap 1.2 Secret1.2.1Secret的应用与Docker仓库 Secret设置1. Kubernetes 中的 Secrets&#xff1a;创建 Secret 示例&#xff1a;将 Secret 挂载到 Pod 中的示例…...

c语言实现bellman-ford算法

下面是使用C语言实现Bellman-Ford算法的示例代码。Bellman-Ford算法用于在带权重的图中找到从单个源点到所有其他顶点的最短路径,它也能处理图中包含负权重边的情况。 #include <stdio.h> #include <stdlib.h> #include <limits.h>// 定义边的结构 struct …...

socket与rpc的区别

如今的游戏开发&#xff0c;不搞个跨服玩法都不好意思说在做游戏了&#xff08;当然&#xff0c;也跟游戏类型有关&#xff0c;一些轻度休闲游戏可以排除在外&#xff09;。跨服玩法的设计&#xff0c;可以进一步激发玩家追求高战力的虚荣心&#xff0c;也可以汇聚玩家数量&…...

10、内网安全-横向移动域控提权NetLogonADCSPACKDC永恒之蓝

用途&#xff1a;个人学习笔记&#xff0c;有所借鉴&#xff0c;欢迎指正&#xff01; 背景&#xff1a; 主要针对内网主机中的 域控提权漏洞&#xff0c;包含漏洞探针和漏洞复现利用。 1、横向移动-系统漏洞-CVE-2017-0146&#xff08;ms17-010&#xff0c;永恒之蓝&#xff0…...

代码随想录算法训练营第三八天 | 动态规划

目录 动态规划基础斐波那契数爬楼梯使用最小花费爬楼梯 LeetCode 509. 斐波那契数 LeetCode 70. 爬楼梯 LeetCode 746. 使用最小花费爬楼梯 动态规划基础 Dynamic Programming (DP) 如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 动态规划中每一个状态…...

【ubuntu2004安装N卡驱动】

软硬件环境 硬件&#xff1a;联想notebook16&#xff0c;显卡4060laptop 软件&#xff1a; ubuntu20.04 驱动安装成功的版本&#xff1a;NVIDIA-Linux-x86_64-535.146.02.run 使用默认的驱动安装&#xff0c;没用原因如下 让手动安装。 手动安装 环境准备&#xff1a; sudo …...

使用 Docker 安装 Kibana 8.4.3

使用 Docker 安装 Kibana 8.4.3 一. 安装启动 Kibana 8.4.3二. 简单使用2.1 向 Elasticsearch 发送请求2.2 搜索2.3 整体页面 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 安装k…...

基于python社交网络大数据分析系统的设计与实现

项目&#xff1a;基于python社交网络大数据分析系统的设计与实现 摘 要 社交网络大数据分析系统是一种能自动从网络上收集信息的工具&#xff0c;可根据用户的需求定向采集特定数据信息的工具&#xff0c;本项目通过研究爬取微博网来实现社交网络大数据分析系统功能。对于采集…...

【设计模式】23种设计模式笔记

设计模式分类 模板方法模式 核心就是设计一个部分抽象类。 这个类具有少量具体的方法&#xff0c;和大量抽象的方法&#xff0c;具体的方法是为外界提供服务的点&#xff0c;具体方法中定义了抽象方法的执行序列 装饰器模式 现在有一个对象A&#xff0c;希望A的a方法被修饰 …...

编程笔记 Golang基础 009 标识符和关键字

编程笔记 Golang基础 009 标识符和关键字 一、标识符二、标识符分类&#xff08;一&#xff09;空白标识符&#xff08;又称下划线 _&#xff09;&#xff08;二&#xff09;预声明标识符&#xff08;三&#xff09;唯一标识符&#xff08;四&#xff09;导出标识符 三、关键字…...

vue3中mockjs模拟获取数据

开发项目的时候&#xff0c;如果后端接口没有出来&#xff0c;前端工程师也不必非得等接口出来才进行下步开发。可以使用mock.js来模拟接口数据&#xff0c;以下就是使用vue3设置hook函数来封装axios请求&#xff0c;配合mock.js来实现的代码&#xff0c;mock的官网 Mock.js 一…...

element ui 添加自定义方法

今天在修改 el-table 源码过程中遇到一个头大的问题&#xff0c;原本修改编译后&#xff0c;将 element的子目录lib下的文件复制到项目的响应目录里就可以了&#xff0c;但是&#xff0c;这次不知为何&#xff0c;编译老是出问题&#xff0c;实在没有办法&#xff0c;我就直接修…...

Hive UDF

当Hive提供的内置函数不能满足查询需求时&#xff0c;用户可以根据自己业务编写自定义函数&#xff08;User Defined Functions, UDF), 然后在HiveQL中调用。 例如有这样一个需求&#xff1a;为了保护用户隐私&#xff0c;当查询数据的时候&#xff0c;需要将用户手机号的中间…...

python Opencv 中绘制图

目录 一:绘制直线 二:绘制矩形 三:绘制圆形 四:绘制椭圆...

imazing软件安全吗?2024中文永久免费许可证

以下是iMazing更多的使用场景描述&#xff1a; iMazing3Mac-最新绿色安装包下载如下&#xff1a; https://wm.makeding.com/iclk/?zoneid49816 iMazing3Win-最新绿色安装包下载如下&#xff1a; https://wm.makeding.com/iclk/?zoneid49817 1. 数据迁移 当你换新的iOS设…...

JavaScript:防抖与节流

文章目录 防抖(Debounce)节流 (Throttle) 在JavaScript中&#xff0c;防抖&#xff08;debounce&#xff09;和节流&#xff08;throttle&#xff09;是两种优化函数调用频率的策略&#xff0c;它们主要用于限制频繁触发的事件回调函数执行次数&#xff0c;以防止过多不必要的计…...

在Win系统部署WampServer并实现公网访问本地服务【内网穿透】

目录 推荐 前言 1.WampServer下载安装 2.WampServer启动 3.安装cpolar内网穿透 3.1 注册账号 3.2 下载cpolar客户端 3.3 登录cpolar web ui管理界面 3.4 创建公网地址 4.固定公网地址访问 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0…...

面试经典150题——单词规律

"Dont wait. The time will never be just right." - Napoleon Hill 1. 题目描述 2. 题目分析与解析 首先还是得把题目先读懂&#xff0c;我们直接来看看示例&#xff1a; 根据上面的示例&#xff0c;我们可以看出pattern其实就是表示单词出现的规律&#xff0c;每…...

RK3568平台开发系列讲解(Linux系统篇)container_of

🚀返回专栏总目录 文章目录 一、理解宏container_of二、使用案例沉淀、分享、成长,让自己和他人都能有所收获!😄 一、理解宏container_of 在代码中管理多个数据结构时,几乎总是需要将一个结构嵌入另一个结构中,并随时检索它们,而不关心有关内存偏移或边界的问题。假设…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...