
本文已配套 5 个可本地运行或可验证的工程,均放在当前目录同级子目录:
jetcache-direct-demo:直接使用 JetCache 的成熟框架方案。l2cache-starter-demo:抽取一个只保留二级缓存能力的轻量 Spring Boot Starter。springboot4-l2cache-demo:Spring Boot 4.1.0 + Java 17 的手工二级缓存示例。layering-cache-boot4-probe:Spring Boot 4.1.0 + Java 17 + Layering Cache 兼容性探针。boot4-internal-l2cache-demo:Spring Boot 4.1.0 + Java 17 的内部二级缓存 starter,对比 JetCache/Layering Cache 迁移。
老李负责一个商品详情服务。大促前压测时,商品详情页 QPS 到 5 万,每次请求都要走远端 Redis,再在未命中时打 MySQL。Redis 本身很快,但网络 RTT、连接池、序列化和热点 key 抖动叠在一起,P99 仍然不够稳。
真正的问题不是“Redis 慢”,而是热点读路径太长:

二级缓存的目标很直接:把最热的数据放到 JVM 内存 L1,把跨节点共享的数据放到 Redis L2。命中 L1 时少一次网络;命中 L2 时少一次数据库;都未命中时再回源,并把结果回填两级缓存。

常见组合是:
二级缓存不是把 Redis 替换掉,而是在 Redis 前面加一层本地热点保护。
读路径要坚持“先近后远、命中回填、失败降级”:

写路径要先保证数据库正确,再处理缓存。多数业务优先选择“写 DB 后删除缓存”,用下一次读重建缓存:

一致性策略可以按业务风险选择:

JetCache 中文文档说明它提供统一 API 和注解,支持 TTL、两级缓存、分布式自动刷新、统计、Caffeine 与 Redis 等实现。2026-06-15 重新校验 Maven metadata 后,jetcache-starter-redis-lettuce 的 latest/release 为 2.8.0.RC,但本文直接示例使用已经本地验证通过的稳定线 2.7.9。
关于 Spring Boot 4:截至 2026-06-16,JetCache 中文文档只声明 JetCache 2.8+ 需要 JDK17、Spring Framework 6.x、Spring Boot 3.x,未声明 Spring Framework 7 / Spring Boot 4 支持;GitHub 上也已有 jetcache-starter-redis-lettuce 什么时候能支持 springboot 4.x 的开放 issue。因此本文不把 JetCache 写成 Boot 4 已支持方案,而是给出内部 starter 迁移样例。
Layering Cache 是竞品方案,Maven metadata 显示 latest/release 为 3.5.0。它更贴近 Spring Cache 注解模型,适合团队已有 Spring Cache 使用习惯、希望以较低迁移成本进入二级缓存的场景。
Layering Cache README 描述它使用 Caffeine 做一级缓存、Redis 做二级缓存;一致性通过“推拉结合”处理,推基于 Redis Pub/Sub,拉基于消息队列与消费偏移。本文新增 layering-cache-boot4-probe,用 Boot 4.1.0 做兼容性验证。
官方系统要求页显示:Spring Boot 4.1.0 至少需要 Java 17,并要求 Spring Framework 7.0.8 或以上。本文的 Boot 4 示例使用 Java 17,避免把尚未验证兼容的 JetCache 强行塞进 Boot 4。
Spring Data Redis 官方文档把 Pub/Sub 分为发布和订阅两类操作,并提供 RedisMessageListenerContainer 来管理订阅连接;本文内部 starter 的分布式 L1 失效广播就基于这个能力实现。
维度 | JetCache 直接使用 | 轻量 starter | Layering Cache 探针 | 手写 Boot 4 示例 | Boot4 内部 starter |
|---|---|---|---|---|---|
核心目标 | 成熟生产框架 | 只保留 L1 + L2 | 验证竞品在 Boot4 下能否落地 | 验证 Boot 4 + Java 17 | JetCache 暂无 Boot4 声明时的内部迁移样例 |
本文工程 |
|
|
|
|
|
注解能力 | 丰富 |
| Layering Cache 注解 | 无框架注解 |
|
自动刷新 | 支持 | 不支持 | 框架声明支持 | 不支持 | 不支持,保持最小能力边界 |
分布式失效 | 框架支持 | 不内置 | 推拉结合 | 不内置 | Redis Pub/Sub 广播 L1 失效 |
序列化 | 多策略 | Jackson 示例 | Kryo/FastJson/Jackson/JDK/Protostuff | JDK 序列化示例 | KryoRedisSerializer |
学习成本 | 中 | 低 | 中 | 低 | 低到中 |
依赖面 | 较大 | 小 | 中 | 小 | 小 |
适合场景 | Boot3 生产通用框架 | 团队想做内部 starter | 竞品评估 | Boot 4 技术预研 | Boot4 迁移与内部可控能力 |
选型流程建议:

目录:20260615/jetcache-direct-demo
技术栈:
3.5.15172.7.9核心代码在 ProductService:
@Cached(
name = "jetcache-direct-demo:product:",
key = "#id",
expire = 300,
localExpire = 60,
cacheType = CacheType.BOTH
)
public Product getProduct(Long id) {
return loadFromDatabase(id);
}工程结构:

本地验证:
cd D:\src\codeup\docsync\20260615\jetcache-direct-demo
$env:JAVA_HOME='C:\Users\Carter.li\scoop\apps\temurin17-jdk\current'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
mvn test
mvn package -DskipTests
docker compose up -d redis
java -jar target\jetcache-direct-demo-1.0.0.jar接口验证:
curl.exe -s http://localhost:18081/api/products/1
curl.exe -s http://localhost:18081/api/products/1
curl.exe -s -X DELETE http://localhost:18081/api/products/1/cache本地验收结果:
步骤 | 关键结果 |
|---|---|
第一次查询 |
|
第二次查询 |
|
删除后查询 |
|
目录:20260615/l2cache-starter-demo
这个工程按用户要求从大框架里抽出一个轻量 starter,只保留二级缓存相关能力,不追求覆盖 JetCache 的全部功能。
模块:
l2cache-spring-boot-starter:starter 本体。l2cache-demo-app:消费 starter 的示例应用。能力边界:

只保留:
@L2Cached@L2CacheEvictL2CacheMode.LOCALL2CacheMode.REMOTEL2CacheMode.BOTH刻意不做:
与 JetCache 的架构对比:

本地验证:
cd D:\src\codeup\docsync\20260615\l2cache-starter-demo
$env:JAVA_HOME='C:\Users\Carter.li\scoop\apps\temurin17-jdk\current'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
mvn test
mvn test package -DskipTests=false
docker compose up -d redis
java -jar l2cache-demo-app\target\l2cache-demo-app-1.0.0.jar接口验证:
curl.exe -s http://localhost:18082/api/products/1
curl.exe -s http://localhost:18082/api/products/1
curl.exe -s -X DELETE http://localhost:18082/api/products/1/cache本地验收结果:
步骤 | 关键结果 |
|---|---|
第一次查询 |
|
第二次查询 |
|
删除后查询 |
|
目录:20260615/springboot4-l2cache-demo
技术栈:
4.1.07.0.817为什么不在 Boot 4 示例里直接上 JetCache:

本地验证过程中也踩到了这个迁移点:首次使用 GenericJackson2JsonRedisSerializer 启动 Boot 4 应用时,因 Jackson 2/3 类型不兼容报 TypeResolverBuilder 缺失。最终示例改为 JdkSerializationRedisSerializer,让文章聚焦二级缓存读写路径。生产如果需要 JSON,应专门设计 Jackson 3 兼容序列化策略。
核心代码:
public Product get(Long id, Supplier<Product> loader) {
Product local = localCache.getIfPresent(id);
if (local != null) {
localHits.incrementAndGet();
return local;
}
Product remote = redisTemplate.opsForValue().get(remoteKey(id));
if (remote != null) {
remoteHits.incrementAndGet();
localCache.put(id, remote);
return remote;
}
misses.incrementAndGet();
Product loaded = loader.get();
if (loaded != null) {
localCache.put(id, loaded);
redisTemplate.opsForValue().set(remoteKey(id), loaded, REMOTE_TTL);
}
return loaded;
}本地验证:
cd D:\src\codeup\docsync\20260615\springboot4-l2cache-demo
$env:JAVA_HOME='C:\Users\Carter.li\scoop\apps\temurin17-jdk\current'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
mvn test
mvn package -DskipTests
docker compose up -d redis
java -jar target\springboot4-l2cache-demo-1.0.0.jar接口验证:
curl.exe -s http://localhost:18083/actuator/health
curl.exe -s http://localhost:18083/api/products/1
curl.exe -s http://localhost:18083/api/products/1
curl.exe -s -X DELETE http://localhost:18083/api/products/1/cache本地验收结果:
步骤 | 关键结果 |
|---|---|
健康检查 |
|
第一次查询 |
|
第二次查询 |
|
删除后查询 |
|
目录:20260615/layering-cache-boot4-probe
技术栈:
4.1.0173.5.0这个工程不是在宣称 Layering Cache 官方已经支持 Boot 4,而是把兼容性风险显性化。实测过程里,原始依赖可以通过 Maven 编译;运行时需要额外补 aspectjweaver、kryo、fastjson 后应用才能启动。随后又发现默认 Kryo 序列化对包含 BigDecimal 的 record 会报 Class is not registered,因此探针模型改成 long priceCents,把关注点收敛到 Boot4、注解切面和二级缓存路径。
核心注解示例:
@Cacheable(
cacheNames = "layering-cache-boot4-probe:product",
key = "#id",
cacheMode = CacheMode.ALL,
firstCache = @FirstCache(expireTime = 60, timeUnit = TimeUnit.SECONDS),
secondaryCache = @SecondaryCache(expireTime = 300, timeUnit = TimeUnit.SECONDS)
)
public Product getProduct(Long id) {
return loadFromDatabase(id);
}兼容性探针流程:

本地验证命令:
cd D:\src\codeup\docsync\20260615\layering-cache-boot4-probe
$env:JAVA_HOME='C:\Users\Carter.li\scoop\apps\temurin17-jdk\current'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
mvn test package -DskipTests=false
java -jar target\layering-cache-boot4-probe-1.0.0.jar --server.port=18084验收结论:
检查项 | 结果 |
|---|---|
Maven 测试与打包 | 通过, |
原始运行时依赖 | 不完整,依次暴露 AspectJ、Kryo、FastJson 缺失 |
补依赖后启动 | 通过, |
Kryo 复杂对象 |
|
二级缓存命中 | 简化模型可返回接口,但未作为 Boot4 生产推荐方案 |
架构判断:Layering Cache 可以作为竞品和迁移参考,但在 Boot 4 上不宜直接认定为生产可用。若团队要用,需要先把依赖传递、序列化注册、Boot 4/Spring 7 自动配置和多节点一致性全部纳入准入测试。
目录:20260615/boot4-internal-l2cache-demo
模块:
internal-l2cache-spring-boot-starter:内部 starter 本体。internal-l2cache-demo-app:业务示例应用。能力边界:
@InternalL2Cached、@InternalL2CacheEvict。KryoRedisSerializer。localHits、remoteHits、misses、puts、evictions、invalidations。内部框架结构:

读路径:

分布式一致性:

为什么不用 JetCache 直接搬到 Boot4:

本地验证命令:
cd D:\src\codeup\docsync\20260615\boot4-internal-l2cache-demo
$env:JAVA_HOME='C:\Users\Carter.li\scoop\apps\temurin17-jdk\current'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
mvn test package -DskipTests=false
docker compose up -d redis双节点验证:
java -jar internal-l2cache-demo-app\target\internal-l2cache-demo-app-1.0.0.jar --server.port=18085 --internal-l2cache.instance-id=node-a
java -jar internal-l2cache-demo-app\target\internal-l2cache-demo-app-1.0.0.jar --server.port=18086 --internal-l2cache.instance-id=node-b实测结果:
步骤 | 关键证据 |
|---|---|
Maven 测试与打包 |
|
节点健康检查 |
|
B 节点第一次读 |
|
B 节点第二次读 |
|
A 节点更新 | 返回 |
B 节点更新后读取 | 返回 |
二级缓存的风险不在“会不会命中”,而在“命中错了怎么办”。

上线前建议检查:
风险 | 检查点 | 建议 |
|---|---|---|
L1 旧值 | 多节点更新后另一个节点是否读旧值 | 对强一致数据缩短 L1 TTL 或使用广播失效 |
缓存穿透 | 不存在 id 是否反复打 DB | 对 null 值设置短 TTL |
缓存击穿 | 热 key 过期瞬间是否大量回源 | 加互斥加载或自动刷新 |
缓存雪崩 | 大量 key 是否同一秒过期 | TTL 加随机抖动 |
序列化迁移 | Boot 4/Jackson 3 是否兼容 | 独立做序列化回归,不混在业务改造里 |
把缓存设计交给 AI 时,不要只问“帮我加缓存”,要给读写比、一致性要求、失效策略和验收方式:
你是 Java 缓存架构顾问。
请基于以下 Service 和 Repository 代码设计 Java 17 + Redis 二级缓存方案。
要求:
AI 生成之后,按下面的验收闭环收口:


结论:
l2cache-starter-demo 已给出最小闭环。springboot4-l2cache-demo 验证底层模型,再用 boot4-internal-l2cache-demo 这种内部 starter 承接注解、序列化和分布式一致性能力。dbLoads 与命中统计。缓存设计不是 PPT 能证明的,它要在本地和流水线里被反复敲打。工程 | 端口 | 启动命令 | 验证接口 |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
有需要demo代码的,请留言。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。