@Service
publicclass UserService {
privatefinal UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// 查询用户信息,优先从缓存获取
@Cacheable(clusterId = "cluster1", prefix = "user", keys = {"#userId"})
public User getUserById(Long userId) {
return userRepository.findById(userId);
}
// 更新用户信息时,自动刷新缓存
@UpdateCache(clusterId = "cluster1", prefix = "user", keys = {"#user.userId"})
public User update(User user) {
return userRepository.update(user);
}
}
-
查询时:自动判断是否命中缓存 -
更新时:自动刷新缓存并保证一致性 -
异常时:触发降级或兜底策略
-
注解拦截:@Cacheable 和 @UpdateCache 触发缓存逻辑 -
统一调度:中央调度器负责协调查询、更新与容错 -
容错机制:防止缓存穿透、缓存击穿等问题 -
多级缓存:Redis + 本地缓存,保障高可用 -
一致性保障:通过 Lua 脚本保证操作原子性
-
请求进入时先访问 Redis -
如果 Redis 异常,触发故障事件,自动降级到本地缓存 -
系统启动探活任务,检测 Redis 是否恢复 -
一旦 Redis 可用,缓存自动升级回 Redis
-
value:缓存数据 -
lockInfo:锁状态(locked/unLock) -
unlockTime:锁过期时间 -
owner:锁持有者
-
读读并发:只有一个线程能查库,其余线程等待或直接读缓存,避免重复查询 -
读写并发:更新线程会强制刷新缓存,保证新数据不会被旧值覆盖 -
弹性过期:缓存不会立即删除,而是“软删除”,允许短时间内读取旧值,避免雪崩
-
Lua 脚本实现原子操作 -
分布式锁确保最终一致性 -
预加载优化性能
-
Redis + 本地缓存双保险 -
宕机自动降级 -
恢复后自动升级
-
标记删除,避免击穿 -
默认 1.5s 异步更新,保证最终一致性 -
支持设置为 0s,强制实时一致
-
一行注解替代上百行缓存逻辑 -
降低学习成本 -
操作模式统一规范
package com.icoderoad;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class EasyCacheApplication {
public static void main(String[] args) {
SpringApplication.run(EasyCacheApplication.class, args);
}
}
spring:
application:
name: easy-cache-demo
redis:
host: 127.0.0.1
port: 6379
password: ""
database: 0
timeout: 5000
# Easy-Cache 自定义配置
easycache:
cluster:
cluster1:
enable: true
expire: 30s # 缓存过期时间
soft-expire: 1s # 弹性过期时间
retry-times: 3 # Redis 故障重试次数
package com.icoderoad.user.model;
publicclass User {
private Long userId;
private String username;
// Getter & Setter
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.icoderoad.user.controller;
import com.icoderoad.user.model.User;
import com.icoderoad.user.service.UserService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
publicclass UserController {
privatefinal UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
// 查询用户
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
// 更新用户
@PostMapping("/update")
public User updateUser(@RequestBody User user) {
return userService.update(user);
}
}
# 查询用户(缓存命中前会访问 repository)
curl http://localhost:8080/users/1
# 更新用户(会自动刷新缓存)
curl -X POST http://localhost:8080/users/update \
-H "Content-Type: application/json" \
-d '{"userId":1,"username":"Tom"}'
-
冗余代码:注解驱动,零重复 -
缓存穿透:内置防护机制 -
缓存击穿:分布式锁与弹性过期机制兜底 -
数据不一致:Redis-Hash + Lua 脚本保障最终一致性 -
Redis 宕机:自动降级 + 探活机制,保障高可用
往期推荐
千万级大表如何删除数据?
开源项目|用Java开发一款AI系统,支持文案/PPT/图片/视频生成
SpringBoot 时间轮实现延时任务
Spring Event,贼好用的业务解耦神器!
Postman替代品:一款极简的网页版 API 调试神器!
不好意思,HttpClient该换了!

