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... (环视系统的外参自…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...