当前位置: 首页> 汽车> 新车 > 沪佳家装客服电话_广州产品设计公司有哪些_网络营销ppt课件_南昌seo外包公司

沪佳家装客服电话_广州产品设计公司有哪些_网络营销ppt课件_南昌seo外包公司

时间:2025/8/25 18:34:24来源:https://blog.csdn.net/musuny/article/details/146085635 浏览次数: 0次
沪佳家装客服电话_广州产品设计公司有哪些_网络营销ppt课件_南昌seo外包公司

30分钟自学教程:Redis缓存穿透原理与解决方案

目标

  1. 理解缓存穿透的成因及危害。
  2. 掌握布隆过滤器、空值缓存等核心防御技术。
  3. 能够通过代码实现请求拦截与缓存保护。
  4. 学会限流降级、异步加载等应急方案。

教程内容

0~2分钟:缓存穿透的定义与核心原因
  • 定义:恶意或异常请求频繁访问数据库中不存在的数据,绕过缓存直接冲击数据库。
  • 典型场景
    • 攻击者伪造大量非法ID(如负数、超长字符串)。
    • 业务未对查询参数校验,或未缓存空结果。
  • 危害
    • 数据库压力激增,甚至宕机。
    • 正常服务被恶意请求拖垮。

2~5分钟:代码模拟穿透场景(Java示例)
// 未做防护的查询方法(模拟穿透问题)  
public Product getProduct(String id) {  String key = "product:" + id;  Product product = redisTemplate.opsForValue().get(key);  if (product == null) {  // 直接查询数据库(未缓存空值)  product = productService.loadFromDB(id);  if (product != null) {  redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS);  }  }  return product; // 恶意请求会反复查询数据库  
}  

验证问题

  • 使用JMeter发送100次id=-1的请求,观察数据库查询次数是否为100次(穿透发生)。

5~12分钟:解决方案1——布隆过滤器(Bloom Filter)
  • 原理:基于位数组和哈希函数,快速判断数据是否可能存在于数据库,拦截非法请求。
  • 代码实现(Redisson布隆过滤器)
// 初始化布隆过滤器并预热合法数据  
public class BloomFilterInit {  private RBloomFilter<String> bloomFilter;  @PostConstruct  public void init() {  bloomFilter = redissonClient.getBloomFilter("product_bloom");  bloomFilter.tryInit(100000L, 0.01); // 容量10万,误判率1%  List<String> validIds = productService.getAllValidIds();  validIds.forEach(bloomFilter::add);  }  
}  // 查询时拦截非法请求  
public Product getProductWithBloomFilter(String id) {  if (!bloomFilter.contains(id)) {  return null; // 直接拦截  }  // 正常查询逻辑...  
}  
  • 注意事项
    • 误判率需根据业务容忍度调整(如0.1%更严格,但占用更多内存)。
    • 需定期同步布隆过滤器与数据库的合法数据(如定时任务)。

12~20分钟:解决方案2——空值缓存(Cache Null)
  • 原理:即使数据库不存在该数据,也缓存空值(如“NULL”),避免重复穿透。
  • 代码实现
public Product getProductWithNullCache(String id) {  String key = "product:" + id;  Product product = redisTemplate.opsForValue().get(key);  if (product == null) {  product = productService.loadFromDB(id);  if (product == null) {  // 缓存空值,5分钟过期  redisTemplate.opsForValue().set(key, "NULL", 5, TimeUnit.MINUTES);  return null;  }  redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS);  } else if ("NULL".equals(product)) {  return null; // 直接返回空结果  }  return product;  
}  
  • 优化点
    • 空值过期时间不宜过长(避免存储大量无效Key)。
    • 可结合布隆过滤器,减少空值缓存的数量。

20~25分钟:解决方案3——请求参数校验
  • 原理:在业务层拦截非法参数(如非数字ID、越界值)。
  • 代码实现(Spring Boot参数校验)
public Product getProduct(@PathVariable String id) {  // 校验ID格式(仅允许数字)  if (!id.matches("\\d+")) {  throw new IllegalArgumentException("非法ID格式");  }  // 校验ID范围(如大于0)  long numericId = Long.parseLong(id);  if (numericId <= 0) {  throw new IllegalArgumentException("ID必须为正数");  }  // 正常查询逻辑...  
}  
  • 扩展
    • 使用Hibernate Validator实现注解式校验(如@Min(1))。

25~28分钟:应急处理方案
  1. 限流降级(Guava RateLimiter)
private RateLimiter rateLimiter = RateLimiter.create(100); // 每秒100个请求  public Product getProduct(String id) {  if (!rateLimiter.tryAcquire()) {  throw new RuntimeException("请求过于频繁,请稍后重试");  }  // 正常查询逻辑...  
}  
  1. 异步加载(CompletableFuture)
public Product getProductAsync(String id) {  String key = "product:" + id;  Product product = redisTemplate.opsForValue().get(key);  if (product == null) {  CompletableFuture.runAsync(() -> {  Product dbProduct = productService.loadFromDB(id);  if (dbProduct != null) {  redisTemplate.opsForValue().set(key, dbProduct, 1, TimeUnit.HOURS);  }  });  }  return product; // 可能返回空,但避免阻塞请求  
}  

28~30分钟:总结与优化方向
  • 核心原则:拦截非法请求、缓存空值、业务兜底。
  • 高级优化
    • 结合Redis Module的RedisBloom扩展(生产级布隆过滤器)。
    • 动态调整限流阈值(如根据数据库负载自动限流)。

练习与拓展

练习

  1. 实现一个布隆过滤器,拦截id<=0的非法请求。
  2. 修改空值缓存逻辑,动态设置随机过期时间(如5~15分钟)。

推荐拓展

  1. 学习RedisBloom模块的安装与使用。
  2. 研究分布式限流框架(如Sentinel)的实现原理。
  3. 探索缓存穿透与缓存击穿的综合防护方案。
关键字:沪佳家装客服电话_广州产品设计公司有哪些_网络营销ppt课件_南昌seo外包公司

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: