大厂五剑客之redis实战分布式缓存彻底解决方案---13----秒杀

场景:获取库存,判断是不是抢到商品的人特别的多。

读多写少:redis。

订单校验:一个用户只能买一个商品。

放在消息队列:订单的写队列。多线程监听,异步入库。

返回用户:订单校验通过之后返回给用户,抢单成功。

---------------------------------------------------------------------------------10-7---------------------------------------------------------------------------------

网关:动态数据的流量拦截。

---------------------------------------------------------------------------------10-8---------------------------------------------------------------------------------

秒杀实战:第二层,网关流量的拦截

1.判断秒杀是不是开始

2.流量拦截

-----

第一步:

  /**
     * 
     * @param uid  当前的用户的id
     * @param skuId 商品的id
     * @return
     */
    @RequestMapping("/redis/seckill")
    public String secKill(int uid,int skuId){
         return seckillService.seckill(uid,skuId);
    }

第二步:

 public String seckill(int uid, int skuId) {
        //流量拦截层
        //1、判断秒杀是否开始   0_1554045087    开始标识_开始时间
        String isStart = (String) redisService.get(secStartPrefix + skuId);
        if (StringUtils.isBlank(isStart)) {
            return "还未开始";
        }
        // 秒杀开始了 拿到标识0是未开始
        if (isStart.contains("_")) {
            Integer isStartInt = Integer.parseInt(isStart.split("_")[0]);
            Integer startTime = Integer.parseInt(isStart.split("_")[1]);
            if (isStartInt == 0) {
                // 未开始要判断是不是开始了到时间了
                if (startTime > getNow()) {
                    return "还未开始";
                } else {
                    //代表秒杀已经开始 置为卡斯hi
                    redisService.set(secStartPrefix + skuId, 1+"");
                }
            } else {
                return "系统异常";
            }
        } else {
            if (Integer.parseInt(isStart) != 1) {
                return "系统异常";
            }
        }
        // 为1就不走上面的步骤 直接开始秒杀了
        // 开始秒杀要进行流量拦截 流量拦截
        //  已经秒杀的商品的数量
        String skuIdAccessName = secAccess + skuId;
        Integer accessNumInt = 0;
        //  已经秒杀商品的数量
        String accessNum = (String) redisService.get(skuIdAccessName);
        if(StringUtils.isNotBlank(accessNum)){
            accessNumInt = Integer.parseInt(accessNum);
        }
        String skuIdCountName = secCount + skuId;
        // 秒杀商品的总数量
        Integer countNumInt = Integer.parseInt((String) redisService.get(skuIdCountName));
        if (countNumInt * 1.2 < accessNumInt) {
            return "抢购已经完成,欢迎下次参与";
        } else {
            // 已经秒杀商品的数量+1
            redisService.incr(skuIdAccessName);
        }
        //信息校验层
        if (redisService.bloomFilterExists(filterName, uid)){
            return "您已经抢购过该商品,请勿重复下发!";
        }else{
            redisService.bloomFilterAdd(filterName, uid);
        }
        Boolean isSuccess = redisService.getAndIncrLua(bookedName+skuId);
        if(isSuccess){
            return "恭喜您抢购成功!!!";
        }else{
            return "抢购结束,欢迎下次参与";
        }
    }

---------------------------------------------------------------------------------10-9---------------------------------------------------------------------------------

布隆过滤器:

一个用户不能抢到两次。

用户的id不能存到内存里面,会挂掉的。

存在redis。就是布隆过滤器。

  //信息校验层
        if (redisService.bloomFilterExists(filterName, uid)){
            return "您已经抢购过该商品,请勿重复下发!";
        }else{
            redisService.bloomFilterAdd(filterName, uid);
        }

---------------------------------------------------------------------------------10-10---------------------------------------------------------------------------------

库存扣减的功能。流量拦截不用lua是追求的高性能的,放入13000也是可以的。

控制超卖必须用lua脚本。

第一步:lua脚本

local lockKey = KEYS[1]

-- get info
local result_1 = redis.call('GET', lockKey)
if tonumber(result_1) <10000
then
local result_2= redis.call('INCR', lockKey)
return result_1
else
return result_1
end

第二步:防止超卖

 Boolean isSuccess = redisService.getAndIncrLua(bookedName+skuId);
        if(isSuccess){
            return "恭喜您抢购成功!!!";
        }else{
            return "抢购结束,欢迎下次参与";
        }

---------------------------------------------------------------------------------10-11---------------------------------------------------------------------------------

发布了308 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_28764557/article/details/104381953