Spring Boot 缓存最佳实践:从基础到生产的完整指南

Spring Boot 缓存最佳实践:从基础到生产的完整指南
引言
在现代分布式系统中,缓存是提升系统性能的银弹。Spring Boot 通过 spring-boot-starter-cache 模块提供了开箱即用的缓存抽象,但如何根据业务需求实现灵活、可靠的缓存方案?本文将带您从零开始,逐步构建符合生产要求的缓存系统。
一、基础篇:5分钟快速接入
1.1 最小化配置
pom.xml 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Nacos 配置(application.yml)
spring:cache:type: simple # 默认内存缓存
启动类注解
@SpringBootApplication
@EnableCaching
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
业务层使用
@Service
public class ProductService {@Cacheable("products")public Product getProduct(Long id) {// 数据库查询逻辑}
}
二、进阶篇:多缓存引擎支持
2.1 缓存类型切换
配置选项对比
| 类型 | 依赖 | 适用场景 | 特点 |
|---|---|---|---|
simple | 内置 | 开发测试环境 | 无过期策略 |
caffeine | com.github.ben-manes.caffeine | 高性能本地缓存 | 支持多种过期策略 |
redis | spring-boot-starter-data-redis | 分布式生产环境 | 支持持久化、集群 |
Nacos 配置示例
spring:cache:type: redis # 切换缓存引擎# Redis 连接配置redis:host: redis.prod.clusterport: 6379password: ${REDIS_PASSWORD}
三、生产级特性实现
3.1 方法级 TTL 控制
实现方式1:语法约定
语法约定
@Cacheable("热点数据#600") // 600秒过期
public HotData getHotData(String key) {// 业务逻辑
}
TTL 解析实现
public class CacheConfig {@Beanpublic CacheManagerCustomizer<RedisCacheManager> redisCacheCustomizer() {return manager -> manager.setCacheDecorator((name, config) -> {String[] parts = name.split("#");if (parts.length > 1) {Duration ttl = Duration.ofSeconds(Long.parseLong(parts[1]));return new RedisCacheWrapper(parts[0], config.entryTtl(ttl));}return new RedisCacheWrapper(name, config);});}
}
实现方式2:自定义注解+AOP切面
- 定义自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheCustomTtl {long value(); // 缓存时间(秒)long jitter() default 10; // 抖动范围(秒)//....自定义其他逻辑
}
- aop切面逻辑
@Aspect
@Component
public class CacheTtlAspect {@Around("@annotation(cacheCustomTtl)")public Object applyCustomTtl(ProceedingJoinPoint joinPoint, CacheCustomTtl cacheCustomTtl) throws Throwable {// 获取原始缓存配置Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();Cacheable cacheable = method.getAnnotation(Cacheable.class);String[] cacheNames = cacheable.value();// 生成带自定义时间的缓存名称(例如: user#3600)String newCacheName = cacheNames[0] + "#" + cacheCustomTtl.value();String[] modifiedCacheNames = {newCacheName};// 动态修改缓存名称Cacheable modifiedCacheable = new CacheableWrapper(cacheable, modifiedCacheNames);((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(Cacheable.class).value();// 通过反射调用原方法(需使用动态代理或工具类)return joinPoint.proceed();}// 包装类用于动态修改注解属性private static class CacheableWrapper implements Cacheable {private final Cacheable delegate;private final String[] cacheNames;public CacheableWrapper(Cacheable delegate, String[] cacheNames) {this.delegate = delegate;this.cacheNames = cacheNames;}@Overridepublic String[] value() { return cacheNames; }// 其他方法委托给原注解...}
}
3.2 随机抖动(Jitter)
防雪崩配置
spring:cache:jitter-range: 60s # 最大抖动时间范围
抖动值生成逻辑
private Duration applyJitter(Duration ttl) {long jitter = ThreadLocalRandom.current().nextLong(spring.cache.jitter-range.getSeconds() + 1);return ttl.plusSeconds(jitter);
}
四、高级优化方案
4.1 多级缓存架构
实现要点
- 使用 Caffeine 作为一级缓存
- Redis 作为二级缓存
- 自定义 CacheManager 实现分级策略
基于Spring Boot的多级缓存架构实现
4.2 监控与治理
Spring Boot Actuator 集成
management:endpoints:web:exposure:include: caches,health,metrics
关键监控指标
-
cache.gets:缓存查询次数 -
cache.puts:缓存写入次数 -
cache.removals:缓存清除次数 -
cache.evictions:缓存淘汰次数
五、最佳实践总结
5.1 配置推荐
# 生产环境推荐配置
spring:cache:type: redisjitter-range: 30skey-separator: "::"redis:lettuce:pool:max-active: 20max-idle: 10min-idle: 5
5.2 避坑指南
-
键设计原则
- 使用业务语义明确的键命名(如
user:profile:{userId}) - 避免使用可变对象作为键
- 使用业务语义明确的键命名(如
-
缓存穿透防护
@Cacheable(value = "users", unless = "#result == null") public User getUser(Long id) {// 返回null时自动跳过缓存 } -
版本兼容策略
@CachePut(value = "products#3600", key = "#product.id") public Product updateProduct(Product product) {// 更新后自动刷新缓存 }
最后
根据业务场景灵活选择适合的缓存策略,从简单的内存缓存到复杂的分布式缓存体系,Spring Boot 的缓存抽象层始终提供一致的使用体验。记住:没有完美的缓存方案,只有最适合业务场景的缓存策略。
相关文章:
Spring Boot 缓存最佳实践:从基础到生产的完整指南
Spring Boot 缓存最佳实践:从基础到生产的完整指南 引言 在现代分布式系统中,缓存是提升系统性能的银弹。Spring Boot 通过 spring-boot-starter-cache 模块提供了开箱即用的缓存抽象,但如何根据业务需求实现灵活、可靠的缓存方案…...
Linux网络相关内容与端口
网络相关命令 ping命令测试连接状态 wget命令:非交互式文件下载器,可以在命令行内下载网络文件 使用ctrlc可以中止下载 curl命令:可以发送http网络请求,用于文件下载、获取信息等 其实和浏览器打开网站一样,cu…...
Python Flask框架学习汇编
1、入门级: 《Python Flask Web 框架入门》 这篇博文条理清晰,由简入繁,案例丰富,分十五节详细讲解了Flask框架,强烈推荐! 《python的简单web框架flask【附例子】》 讲解的特别清楚,每一步都…...
GitHub CI流水线
GitHub CI流水线 build.yml 路径:.github/workflows/build.yml name: Docker Image CIon:workflow_dispatch:jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkoutv4- name: Set up JDK 8uses: actions/setup-javav4with:java-version: 8distributi…...
机器视觉运动控制一体机在天地盖同步跟随贴合解决方案
市场应用背景 纸盒天地盖是一种包装形式,广泛应用于消费电子、食品礼盒、奢侈品及化妆品等领域。其采用高强度纸板,经过预组装处理,结构坚固稳定,能有效保护产品并提升品牌形象。随着包装行业快速发展,市场对天地盖的…...
贪心算法一
> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:了解什么是贪心算法,并且掌握贪心算法。 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! >…...
什么是全栈?
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点下班 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 📃文章前言 🔷文章均为学习工…...
后端-Java虚拟机
Java虚拟机 Java虚拟机的组成 Java虚拟机的组成由类加载器ClassLoader、运行时数据区域(JVM管理的内存)和执行引擎(即时遍历器、解释器垃圾回收器) 类加载器加载class字节码文件中的内容到内存运行时数据区域负责管理jvm使用到…...
Android 低功率蓝牙之BluetoothGattCallback回调方法详解
BluetoothGattCallback 是 Android 中用于处理蓝牙低功耗(BLE)设备通信的核心回调类。它负责处理与 BLE 设备的连接、服务发现、数据读写等操作的结果。以下是对 BluetoothGattCallback 的详细解析: 1. onConnectionStateChange 触发时机&am…...
K8S学习之基础十四:k8s中Deployment控制器概述
Deployment控制器概述: Deployment控制器是k8s中最常用的资源对象,为Replicaset和Pod创建提供了一种声明式的定义方法,在Deployment对象中描述一个期望的状态,Deployment控制器就会按照一定的控制速率把实际状态改成期望状态&…...
Vue3快速入门笔记
目录 1.Vue3简介1.1.性能提升1.2.源码升级1.3.拥抱TypeScript1.4.新特性 2.创建Vue3工程2.1.基于 vue-cli 创建2.2. 基于 vite 创建(推荐)2.3.代码运行 3.Vue3核心语法3.1.OptionsAPI(选项式API) 与 CompositionAPI(组合式API)3.2.setup3.3.ref 创建&…...
【LeetCode104】二叉树的最大深度
题目 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 思路与算法 树的最大深度可以通过其左子树和右子树的最大深度来定义。对于给定节点,最大深度为 1(当前节点࿰…...
SQLAlchemy系列教程:理解SQLAlchemy元数据
SQLAlchemy是Python开发人员的强大ORM工具。SQLAlchemy中的元数据是对象-关系映射配置的集合,允许开发人员无缝地定义和使用数据库模式。 使用元数据 SQLAlchemy中的元数据充当各种数据库描述符(如表、列和索引)的容器。这使开发人员能够通…...
Apache Shiro 反序列化漏洞全解析(Shiro-550 Shiro-721)
一、前言 Apache Shiro 是一个强大的 Java 安全框架,广泛用于用户认证、授权、加密和会话管理。然而,由于 Shiro 在某些版本中存在反序列化漏洞,攻击者可以通过特定手法实现远程代码执行(RCE),进而获取服务…...
计算机毕业设计Python+DeepSeek-R1大模型空气质量预测分析(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
实例详细演示在Pytest中如何忽略警告
关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理,构建成功的基石 在自动化测试工作之前,你应该知道的10条建议 在自动化测试中,重要的不是工具 当你尝试运行Pytest代码时,那些不相关的警告突然弹出,是不是…...
03 HarmonyOS Next仪表盘案例详解(二):进阶篇
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! 文章目录 前言1. 响应式设计1.1 屏幕适配1.2 弹性布局 2. 数据展示与交互2.1 数据卡片渲染2.2 图表区域 3. 事件处理机制3.1 点击事件处理3.2 手势…...
mysql进阶(三)
MySQL架构和存储引擎 1. MySQL架构 MySQL8.0服务器是由连接池、服务管理⼯具和公共组件、NoSQL接⼝、SQL接⼝、解析器、优化 器、缓存、存储引擎、⽂件系统组成。MySQL还为各种编程语⾔提供了⼀套⽤于外部程序访问服务器 的连接器。整体架构图如下所⽰: 2. 连接层 …...
MySQL 架构、索引优化、DDL解析、死锁排查
私人博客传送门 MySQL 认识索引 | 魔筝炼药师 MySQL 索引优化 | 魔筝炼药师 OnlineDDL(在 MySQL 5.7 数据库里,InnoDB引擎,执行一条DDL会发生什么事情) | 魔筝炼药师 MySQL 死锁排查 | 魔筝炼药师...
AVM 环视拼接 鱼眼相机
https://zhuanlan.zhihu.com/p/651306620 AVM 环视拼接方法介绍 从内外参推导IPM变换方程及代码实现(生成AVM环视拼接图)_avm拼接-CSDN博客 经典文献阅读之--Extrinsic Self-calibration of the Surround-view System: A Weakly... (环视系统的外参自…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
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任务 三、…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
