关于java:秒杀场景如何通过-Redis-减库存

30次阅读

共计 2219 个字符,预计需要花费 6 分钟才能阅读完成。

Redis 预减库存

次要思路缩小对数据库的拜访,之前的减库存,间接拜访数据库,读取库存,当高并发申请到来的时候,大量的读取数据有可能会导致数据库的解体。

思路:

  1. 零碎初始化的时候,将商品库存加载到 Redis 缓存中保留
  2. 收到申请的时候, 当初 Redis 中拿到该商品的库存值,进行库存预减,如果减完之后库存有余,间接返回逻辑 Exception 就不须要拜访数据库再去减库存了,如果库存值正确,进行下一步
  3. 将申请入队,立刻给前端返回一个值,示意正在排队中,而后进行秒杀逻辑,后端队列进行秒杀逻辑,前端轮询后端发来的申请,如果秒杀胜利,返回秒杀,胜利,不胜利就返回失败。

(后端申请 单线程 出队,生成订单,缩小库存,走逻辑)前端同时轮询

  1. 前端显示

第一步:预减库存

/**
 * 秒杀接口优化之 ---   第一步:  零碎初始化后就将所有商品库存放入 缓存
 */
@Override
public void afterPropertiesSet() throws Exception {List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {return;}
    for (GoodsVo goodsVo : goods) {redisService.set(GoodsKey.getGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);// 先初始化 每个商品都是 false 就是还有
    }
}
/** 秒杀接口优化之 ---- 第二步:预减库存 从缓存中减库存
 * 利用 redis 中的办法,减去库存,返回值为 减去 1 之后的值
 * */
long stock = redisService.decr(GoodsKey.getGoodsStock, "" + goodsId);
/* 这里判断不能小于等于,因为减去之后等于 阐明还有是失常范畴 */
if (stock < 0) {isOverMap.put(goodsId, true);// 没有库存就设置 对应 id 商品的 map 为 true
    return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
}

预减库存:

1. 先将所有数据读出来,初始化到缓存中,并以 stock + goodid 的造成存入 Redis,

2. 在秒杀的时候,先进行预减库存检测,从 redis 中,利用 decr 减去对应商品的库存,如果库存小于 0,阐明此时 库存有余,则不须要拜访数据库。间接抛出异样即可

内存标记:

因为接口优化很多基于 Redis 的缓存操作,当并发很高的时候,也会给 Redis 服务器带来很大的累赘,如果能够缩小对 Redis 服务器的拜访,也能够达到的优化的成果。

于是,能够加一个内存 map, 标记对应商品的库存量是否还有,在拜访 Redis 之前,在 map 中拿到对应商品的库存量标记,就能够不须要拜访 Redis 就能够判断没有库存了。

1. 生成一个 map,并在初始化的时候,将所有商品的 id 为键,标记 false 存入 map 中。

private Map<Long, Boolean> isOverMap = new HashMap<Long, Boolean>();

/**
 * 秒杀接口优化之 ---   第一步:  零碎初始化后就将所有商品库存放入 缓存
 */
@Override
public void afterPropertiesSet() throws Exception {List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {return;}
    for (GoodsVo goodsVo : goods) {redisService.set(GoodsKey.getGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);// 先初始化 每个商品都是 false 就是还有
    }
}
    /** 再优化:优化 库存之后的申请不拜访 redis 通过判断 对应 map 的值
     * */
    boolean isOver = isOverMap.get(goodsId);
    if (isOver) {return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
    }


    if (stock < 0) {isOverMap.put(goodsId, true);// 没有库存就设置 对应 id 商品的 map 为 true

2. 在预减库存之前,从 map 中取标记,若标记为 false, 阐明库存,还有,

3. 预减库存,当遇到库存有余的时候,将该商品的标记置为 true, 示意该商品的库存有余。这样,上面的所有申请,将被拦挡,无需拜访 redis 进行预减库存。

原文链接:https://blog.csdn.net/weixin_…

版权申明:本文为 CSDN 博主「Dandy1awcoder」的原创文章,遵循 CC 4.0 BY-SA 版权协定,转载请附上原文出处链接及本申明。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿 (2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0