缓存穿透
攻击者可以恶意请求数据库中不存在的数据,从而使得每次查询都要绕过缓存查数据库,增大数据库的压力。
解决方案:
1.缓存空值:比如塞一个空字符串。注意可以给空对象的键过期时间设置短一些,或者在新增数据时强制清除下对应缓存(防止查出来还是 null)
2.布隆过滤器
预防做法:
1.增强对请求数据的校验,比如 id > 0
2.增强对数据格式的控制,比如 id 设置为 10 位,不为 10 位的请求直接拒绝
3.增强用户权限校验
4.通过限流来保护数据库
修改后的代码
@Override
public Result queryById(Long id) {
String key = CACHE_SHOP_KEY + id;
// 1.从redis查询商铺缓存
String shopJson = stringRedisTemplate.opsForValue().get(key);
// 2.判断是否存在
if (StrUtil.isNotBlank(shopJson)) {
// 3.存在,直接返回
Shop shop = JSONUtil.toBean(shopJson, Shop.class);
return Result.ok(shop);
}
// 判断命中的是否是空值
if (shopJson != null) {
// 返回一个错误信息
return Result.fail("店铺不存在!");
}
// 4.不存在,根据id查询数据库
Shop shop = getById(id);
if (shop == null){
// 将空值写入redis
stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL, TimeUnit.MINUTES);
// 5.不存在返回错误
return Result.fail("店铺不存在!");
}
// 6.存在,写入redis
stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
// 7.返回
return Result.ok(shop);
}
标签:shop,shopJson,缓存,return,Redis,穿透,Result,id
From: https://www.cnblogs.com/ysk0904/p/17717784.html