Redisson分布式锁+AOP
1. Redisson分布式锁的简单使用
1.1 防止缓存击穿
假如系统中的某个资源获取非常活跃,即使加了Redis缓存,在缓存失效的一瞬间,大量的请求会打进数据库,这时可能会导致数据库线程资源打满,严重情况下可能会宕机,这种情况下在重建缓存的时候需要加分布式锁 (理论上 synchronized 级别的锁也可以解决,这样重建缓存的线程就等于当前服务实例的个数)。
/**
* @author wangxun
*/
@Slf4j
@RestController
@RequestMapping("/user")
@Api(tags = "用户Controller")
public class UserController extends BaseController {
// 自定义的,为了实现动态修改缓存的失效时间
@Autowired
private RedisKeyProperties redisKeyProperties;
// RedisTemplate.opsForValue()
@Autowired
private ValueOperations<String, Object> valueOperations;
// RedissonClient
@Autowired
private RedissonClient redissonClient;
// com.github.benmanes.caffeine.cache.Caffeine 的本地缓存
@Autowired
private Cache<String, User> localCache;
@PostMapping("/getById/{id}")
public Result<User> getById(@PathVariable Long id) throws InterruptedException {
return success(getById01(id));
// return success(getById02(id));
// return success(getById03(id));
// return success(getById04(id));
}
// 伪代码,代码没有规范化
private User getById01(Long id) {
String redisKey = redisKeyProperties.getUser().getRedisKey().replace("{id}", id.toString());
// TODO: 一级缓存中获取
User user = localCache.getIfPresent(redisKey);
if (Objects.nonNull(user)) {
return user;
}
// TODO: 二级缓存中获取
user = (User) valueOperations.get(redisKey);
if (Objects