Redis的manager层应用
AI-摘要
Tianli GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
封装了一个操作redis的管理层,简单处理了缓存穿透、击穿、雪崩问题
- 接口
/**
* redis管理层
*/
public interface RedisManager {
/**
* 从缓存中获取否则从mysql中查询
*
* @param key 缓存中的key
* @param mysqlSupplier 查询mysql操作
* @param typeReference 返回的类型
* @param <T> 数据类型
* @return 数据
*/
<T> T getFromRedisOrPutIntoMysql(String key, Supplier<T> mysqlSupplier, TypeReference<T> typeReference);
}
- 实现类
/**
* redis管理层实现类
*
*/
@Service
public class RedisManagerImpl implements RedisManager {
public static final SecureRandom SECURE_RANDOM = new SecureRandom();
/**
* 过期时间
*/
public static final int EXPIRE_SECONDS = 5 * 60 * 1000;
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 从缓存中获取否则从mysql中查询
*
* @param key 缓存中的key
* @param mysqlSupplier 查询mysql操作
* @param typeReference 返回的类型
* @param <T> 数据类型
* @return 数据
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED, isolation = Isolation.READ_UNCOMMITTED)
public <T> T getFromRedisOrPutIntoMysql(String key, Supplier<T> mysqlSupplier, TypeReference<T> typeReference) {
// 判断传入key是否为空
Opt.ofNullable(key).filter(StringUtils::isNotEmpty)
.orElseThrow(() -> new MybatisPlusException("key不能为空"));
// 如果redis中存在,直接返回
String value = stringRedisTemplate.opsForValue().get(key);
if (Objects.nonNull(value)) {
return JSON.parseObject(value, typeReference);
}
// 查数据库并放入缓存这个操作加锁【缓存击穿】
synchronized (this) {
// 否则从数据库中取出
return Opt.ofNullable(mysqlSupplier).map(Supplier::get)
// 如果有值则放入缓存,随机时间【缓存雪崩】
.peek(v -> stringRedisTemplate.opsForValue()
.set(key, JSON.toJSONString(v), SECURE_RANDOM.nextInt(EXPIRE_SECONDS), TimeUnit.SECONDS))
// 没值则放入空对象"{}"【缓存穿透】并返回null
.orElseGet(() -> {
stringRedisTemplate.opsForValue()
.set(key, "{}", SECURE_RANDOM.nextInt(EXPIRE_SECONDS), TimeUnit.SECONDS);
return null;
});
}
}
}
- 使用
@Resource
private RedisManager redisManager;
@Test
public void managerTest() {
List<String> userIds = redisManager.getFromRedisOrPutIntoMysql("userIds", () -> {
// 从数据库中查询...
return Arrays.asList("1", "2", "3");
}, new TypeReference<List<String>>() {
});
System.out.println(userIds);
}
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 leaflei
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果