JAVA语言企业项目实战(四)

简介: 教程来源 http://oplhc.cn/category/artificial-intelligence.html 本节详解秒杀系统缓存优化:通过Redis预热热点数据降低数据库压力;针对缓存穿透(空值缓存)、击穿(分布式锁+双重检查)、雪崩(随机过期时间)三大问题,提供可落地的解决方案,全面提升系统并发性能与稳定性。

第四部分:缓存与性能优化:让系统飞起来

4.1 Redis缓存策略:热点数据预热
秒杀活动开始前,需要将商品信息预热到Redis中。

@Service
public class CacheService {

    @PostConstruct
    public void initCache() {
        log.info("开始预热商品缓存...");
        List<SeckillGoods> goodsList = seckillGoodsMapper.selectList(null);

        for (SeckillGoods goods : goodsList) {
            // 缓存商品详情
            String goodsKey = "seckill:goods:" + goods.getId();
            redisTemplate.opsForValue().set(goodsKey, goods, 1, TimeUnit.HOURS);

            // 缓存商品库存(用于秒杀预减)
            String stockKey = "seckill:stock:" + goods.getId();
            redisTemplate.opsForValue().set(stockKey, goods.getStockCount());

            log.info("缓存商品: id={}, stock={}", goods.getId(), goods.getStockCount());
        }
    }
}

为什么需要预热?
秒杀开始时,大量请求会查询商品信息
如果缓存是空的,所有请求都会打到数据库,数据库瞬间被打垮
预热让缓存提前准备好,数据库压力大大降低

4.2 缓存三大问题及解决方案
问题一:缓存穿透
缓存穿透是指查询一个不存在的数据。由于缓存中没有,请求会直接打到数据库。恶意攻击者可以利用这一点,用大量不存在的key攻击系统。
解决方案:缓存空值

public SeckillGoods getGoods(Long goodsId) {
    // 先从缓存获取
    SeckillGoods goods = redisTemplate.opsForValue().get("goods:" + goodsId);
    if (goods != null) {
        return goods;
    }

    // 缓存没有,查询数据库
    goods = seckillGoodsMapper.selectById(goodsId);

    if (goods != null) {
        // 存在,写入缓存
        redisTemplate.opsForValue().set("goods:" + goodsId, goods);
    } else {
        // 不存在,缓存空对象(设置较短过期时间)
        redisTemplate.opsForValue().set("goods:" + goodsId, new SeckillGoods(), 60);
    }

    return goods;
}

问题二:缓存击穿

缓存击穿是指一个热点key过期瞬间,大量请求同时打到数据库。

解决方案:分布式锁

public SeckillGoods getGoodsWithLock(Long goodsId) {
    SeckillGoods goods = redisTemplate.opsForValue().get("goods:" + goodsId);
    if (goods != null) {
        return goods;
    }

    // 尝试获取锁
    RLock lock = redissonClient.getLock("goods:lock:" + goodsId);
    if (lock.tryLock()) {
        try {
            // 双重检查
            goods = redisTemplate.opsForValue().get("goods:" + goodsId);
            if (goods != null) {
                return goods;
            }

            // 查询数据库
            goods = seckillGoodsMapper.selectById(goodsId);
            redisTemplate.opsForValue().set("goods:" + goodsId, goods);
        } finally {
            lock.unlock();
        }
    } else {
        // 等待一小段时间后重试
        Thread.sleep(100);
        return getGoodsWithLock(goodsId);
    }

    return goods;
}

问题三:缓存雪崩

缓存雪崩是指大量缓存同时过期,导致数据库压力骤增。

解决方案:随机过期时间

// 设置随机过期时间,避免同时失效
int randomTtl = 3600 + new Random().nextInt(600);  // 3600~4200秒
redisTemplate.opsForValue().set(key, value, randomTtl, TimeUnit.SECONDS);

来源:
http://oplhc.cn/

相关文章
|
6天前
|
人工智能 数据可视化 安全
王炸组合!阿里云 OpenClaw X 飞书 CLI,开启 Agent 基建狂潮!(附带免费使用6个月服务器)
本文详解如何用阿里云Lighthouse一键部署OpenClaw,结合飞书CLI等工具,让AI真正“动手”——自动群发、生成科研日报、整理知识库。核心理念:未来软件应为AI而生,CLI即AI的“手脚”,实现高效、安全、可控的智能自动化。
18003 12
王炸组合!阿里云 OpenClaw X 飞书 CLI,开启 Agent 基建狂潮!(附带免费使用6个月服务器)
|
17天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
29540 141
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
7天前
|
人工智能 JSON 监控
Claude Code 源码泄露:一份价值亿元的 AI 工程公开课
我以为顶级 AI 产品的护城河是模型。读完这 51.2 万行泄露的源码,我发现自己错了。
4597 20
|
5天前
|
人工智能 API 开发者
阿里云百炼 Coding Plan 售罄、Lite 停售、Pro 抢不到?最新解决方案
阿里云百炼Coding Plan Lite已停售,Pro版每日9:30限量抢购难度大。本文解析原因,并提供两大方案:①掌握技巧抢购Pro版;②直接使用百炼平台按量付费——新用户赠100万Tokens,支持Qwen3.5-Max等满血模型,灵活低成本。
1440 3
阿里云百炼 Coding Plan 售罄、Lite 停售、Pro 抢不到?最新解决方案