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

基于Spring Boot的多级缓存架构实现

基于Spring Boot的多级缓存架构实现

以下是一个基于Spring Boot的多级缓存架构实现示例


多级缓存架构实现方案

1. 依赖配置(pom.xml)
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 缓存配置类
@Configuration
@EnableCaching
public class MultiLevelCacheConfig {// 一级缓存(本地缓存)@Beanpublic CacheManager caffeineCacheManager() {CaffeineCacheManager manager = new CaffeineCacheManager();manager.setCaffeine(Caffeine.newBuilder().maximumSize(1000).expireAfterWrite(30, TimeUnit.SECONDS)); // 本地缓存比Redis缓存更短return manager;}// 二级缓存(Redis缓存)@Beanpublic CacheManager redisCacheManager(RedisConnectionFactory factory) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()));return RedisCacheManager.builder(factory).cacheDefaults(config).transactionAware().build();}// 组合缓存管理器@Bean@Primarypublic CacheManager multiLevelCacheManager(@Qualifier("caffeineCacheManager") CacheManager level1,@Qualifier("redisCacheManager") CacheManager level2) {return new MultiLevelCacheManager(level1, level2);}
}
3. 多级缓存管理器实现
public class MultiLevelCacheManager implements CacheManager {private final CacheManager level1; // 本地缓存private final CacheManager level2; // Redis缓存private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>();public MultiLevelCacheManager(CacheManager level1, CacheManager level2) {this.level1 = level1;this.level2 = level2;}@Overridepublic Cache getCache(String name) {return cacheMap.computeIfAbsent(name, key -> new MultiLevelCache(level1.getCache(name), level2.getCache(name)));}@Overridepublic Collection<String> getCacheNames() {return Stream.concat(level1.getCacheNames().stream(),level2.getCacheNames().stream()).collect(Collectors.toSet());}// 多级缓存实现static class MultiLevelCache implements Cache {private final Cache level1;private final Cache level2;private final String name;public MultiLevelCache(Cache level1, Cache level2) {this.level1 = level1 != null ? level1 : new NoOpCache();this.level2 = level2 != null ? level2 : new NoOpCache();this.name = level1.getName() + ":" + level2.getName();}@Overridepublic String getName() {return name;}@Overridepublic Object getNativeCache() {return this;}@Overridepublic ValueWrapper get(Object key) {// 先查一级缓存ValueWrapper value = level1.get(key);if (value == null) {// 二级缓存查询value = level2.get(key);if (value != null) {// 回填一级缓存level1.put(key, value.get());}}return value;}@Overridepublic <T> T get(Object key, Class<T> type) {// 实现逻辑类似get方法T value = level1.get(key, type);if (value == null) {value = level2.get(key, type);if (value != null) {level1.put(key, value);}}return value;}@Overridepublic void put(Object key, Object value) {// 同时写入两级缓存level1.put(key, value);level2.put(key, value);}@Overridepublic void evict(Object key) {// 同时清除两级缓存level1.evict(key);level2.evict(key);}@Overridepublic void clear() {level1.clear();level2.clear();}}// 空缓存实现(容错)static class NoOpCache implements Cache {// 实现基础的Cache方法,返回空值}
}
4. 业务层使用
@Service
public class ProductService {@Cacheable(value = "products", key = "#id")public Product getProduct(Long id) {// 数据库查询逻辑return productRepository.findById(id).orElseThrow(() -> new NotFoundException("Product not found"));}@CacheEvict(value = "products", key = "#product.id")public void updateProduct(Product product) {productRepository.save(product);}
}
5. 配置说明(application.yml)
spring:cache:multi-level:level1:ttl: 30s    # 本地缓存时间max-size: 1000level2:ttl: 5m     # Redis缓存时间redis:host: redis-cluster.prodport: 6379timeout: 2000ms

关键实现要点

  1. 缓存层级策略
Client Level1 Level2 DB 查询缓存 命中返回 查询二级缓存 返回结果 返回结果 查询数据库 返回数据 回填数据 返回数据 alt [二级缓存未命中] alt [未命中] Client Level1 Level2 DB
  1. 一致性保障
  • 写操作:同时清除两级缓存(@CacheEvict​)
  • 读操作:二级缓存命中后自动回填一级缓存
  • TTL策略:一级缓存TTL(30s) < 二级缓存TTL(5m)
  1. 性能优化
  • 本地缓存:使用Caffeine高性能缓存库
  • 异步回填:可扩展为异步加载(需自定义CacheLoader)
  • 批量操作:支持@Cacheable的批量查询优化

扩展建议

  1. 缓存预热
@PostConstruct
public void preloadHotData() {// 加载热点数据到缓存hotProducts.forEach(product -> cacheManager.getCache("products").put(product.getId(), product));
}
  1. 监控集成
@Bean
public MeterRegistryCustomizer<MeterRegistry> cacheMetrics() {return registry -> {CaffeineCacheManager caffeine = context.getBean(CaffeineCacheManager.class);RedisCacheManager redis = context.getBean(RedisCacheManager.class);// 注册Caffeine监控CacheMetrics.monitor(registry, caffeine, "level1");// 注册Redis监控CacheMetrics.monitor(registry, redis, "level2");};
}
  1. 防雪崩策略
// 在MultiLevelCache.get方法中添加
ValueWrapper get(Object key) {try {// 添加分布式锁检查if (lockManager.tryLock(key)) {// 实际查询逻辑}} finally {lockManager.unlock(key);}
}

相关文章:

基于Spring Boot的多级缓存架构实现

基于Spring Boot的多级缓存架构实现 以下是一个基于Spring Boot的多级缓存架构实现示例 多级缓存架构实现方案 1. 依赖配置&#xff08;pom.xml&#xff09; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…...

Git与GitHub:理解两者差异及其关系

目录 Git与GitHub&#xff1a;理解两者差异及其关系Git&#xff1a;分布式版本控制系统概述主要特点 GitHub&#xff1a;基于Web的托管服务概述主要特点 Git和GitHub如何互补关系现代开发工作流 结论 Git与GitHub&#xff1a;理解两者差异及其关系 Git&#xff1a;分布式版本控…...

ALG(Alloy+Loki+Grafana)轻量级日志系统

ALG(AlloyLokiGrafana)轻量级日志系统 前提要求 GrafanaMinioNginxPrometheus Grafana日志收集系统旧版是PLG(ProtailLokiGrafana), Protail收集日志, Loki存储, Grafana展示, 后续的Protail不维护了, Grafana推出了Alloy代替Pritial, 除了收集日志外, 还集成管理Prometheus各种…...

【漫话机器学习系列】121.偏导数(Partial Derivative)

偏导数&#xff08;Partial Derivative&#xff09;详解 1. 引言 在数学分析、机器学习、物理学和工程学中&#xff0c;我们经常会遇到多个变量的函数。这些函数的输出不仅取决于一个变量&#xff0c;而是由多个变量共同决定的。那么&#xff0c;当其中某一个变量发生变化时&…...

Deepseek可以通过多种方式帮助CAD加速工作

自动化操作&#xff1a;通过Deepseek的AI能力&#xff0c;可以编写脚本来自动化重复性任务。例如&#xff0c;使用Python脚本调用Deepseek API&#xff0c;在CAD中实现自动化操作。 插件开发&#xff1a;结合Deepseek进行二次开发&#xff0c;可以创建自定义的CAD插件。例如&a…...

【工具使用】IDEA 社区版如何创建 Spring Boot 项目(详细教程)

IDEA 社区版如何创建 Spring Boot 项目&#xff08;详细教程&#xff09; Spring Boot 以其简洁、高效的特性&#xff0c;成为 Java 开发的主流框架之一。虽然 IntelliJ IDEA 专业版提供了Spring Boot 项目向导&#xff0c;但 社区版&#xff08;Community Edition&#xff09…...

QT中串口打开按钮如何点击打开后又能点击关闭

前言&#xff1a; if (!portOpen) { // 打开串口 if (!sp18Controller->initializePort("COM5", 38400)) { QMessageBox::critical(this, "Error", "Failed to open serial port."); return; } ui->btnOpenPort_2->setText("Close…...

【AI深度学习基础】PyTorch初探

引言 PyTorch 是由 Facebook 开源的深度学习框架&#xff0c;专门针对 GPU 加速的深度神经网络编程&#xff0c;它的核心概念包括张量&#xff08;Tensor&#xff09;、计算图和自动求导机制。PyTorch作为Facebook开源的深度学习框架&#xff0c;凭借其动态计算图和直观的API设…...

springboot011基于springboot的课程作业管理系统(源码+包运行+LW+技术指导)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得难了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等&#xff0c;你想解决的问题&#xff0c;今天…...

快速从C过度C++(一):namespace,C++的输入和输出,缺省参数,函数重载

&#x1f4dd;前言&#xff1a; 本文章适合有一定C语言编程基础的读者浏览&#xff0c;主要介绍从C语言到C过度&#xff0c;我们首先要掌握的一些基础知识&#xff0c;以便于我们快速进入C的学习&#xff0c;为后面的学习打下基础。 这篇文章的主要内容有&#xff1a; 1&#x…...

PostgreSQL时间计算大全:从时间差到时区转换(保姆级教程)

一、时间计算的三大核心场景 当你遇到这些需求时&#xff0c;本文就是你的救星&#x1f31f;&#xff1a; 倒计时功能&#xff1a;计算活动剩余天数 用户行为分析&#xff1a;统计操作间隔时间 跨国系统&#xff1a;多时区时间统一管理 报表生成&#xff1a;自动计算同比/环…...

laravel es 相关代码 ElasticSearch

来源&#xff1a; github <?phpnamespace App\Http\Controllers;use Elastic\Elasticsearch\ClientBuilder; use Illuminate\Support\Facades\DB;class ElasticSearch extends Controller {public $client null;public function __construct(){$this->client ClientB…...

题目 3220 ⭐因数计数⭐【数理基础】蓝桥杯2024年第十五届省赛

小蓝随手写出了含有 n n n 个正整数的数组 a 1 , a 2 , ⋅ ⋅ ⋅ , a n {a_1, a_2, , a_n} a1​,a2​,⋅⋅⋅,an​ &#xff0c;他发现可以轻松地算出有多少个有序二元组 ( i , j ) (i, j) (i,j) 满足 a j a_j aj​ 是 a i a_i ai​ 的一个因数。因此他定义一个整数对 …...

【Java代码审计 | 第十一篇】SSRF漏洞成因及防范

未经许可&#xff0c;不得转载。 文章目录 SSRF漏洞成因Java中发送HTTP请求的函数1、HttpURLConnection2、HttpClient&#xff08;Java 11&#xff09;3、第三方库Request库漏洞示例OkHttpClient漏洞示例HttpClients漏洞示例 漏洞代码示例防范标准代码 SSRF SSRF&#xff08;S…...

RabbitMQ高级特性--消息确认机制

目录 一、消息确认 1.消息确认机制 2.手动确认方法 二、代码示例 1. AcknowledgeMode.NONE 1.1 配置文件 1.2 生产者 1.3 消费者 1.4 运行程序 2.AcknowledgeMode.AUTO 3.AcknowledgeMode.MANUAL 一、消息确认 1.消息确认机制 生产者发送消息之后&#xff0c;到达消…...

C++复试笔记(一)

Setw 是C中用于设置输出字段宽度的函数。当使用 setw(3) 时&#xff0c;它会设置紧接着的输出字段的最小宽度为3个字符。如果字段内容长度小于3&#xff0c;则会在左侧填充空格以达到指定宽度&#xff1b;如果内容长度大于或等于3&#xff0c;则全部内容将被输出&#xff0c;…...

K8s 1.27.1 实战系列(四)验证集群及应用部署测试

一、验证集群可用性 1、检查节点 kubectl get nodes ------------------------------------------------------ NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 3h48m v1.27.1 k8s-node1 Ready <none> …...

基于Spring Boot的健美操评分管理系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

H5页面在移动端自动横屏

首先需要再head标签添加这样一段代码 <meta name="viewport" content="width=device-width,height=device-width,initial-scale=1.0,user-scalable=no">因为需求是为了满足WEB端和手机端都可以查看整体效果 但由于UI没有设计移动端的样式 所以我想说…...

【从0到1搞懂大模型】神经网络的实现:数据策略、模型调优与评估体系(3)

一、数据集的划分 &#xff08;1&#xff09;按一定比例划分为训练集和测试集 我们通常取8-2、7-3、6-4、5-5比例切分&#xff0c;直接将数据随机划分为训练集和测试集&#xff0c;然后使用训练集来生成模型&#xff0c;再用测试集来测试模型的正确率和误差&#xff0c;以验证…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...