商品秒杀上架的基本实现

秒杀活动属于会员系统中的功能,但是秒杀的接口压力巨大所以需要把它独立出来。

秒杀活动表 :优惠系统中有定义秒杀场次,描述了秒杀活动id,活动开始时间,活动结束时间,这个在前端创建秒杀活动时有时间选择器,在查找秒杀活动列表页中记录可以添加关联表数据,根据活动id关联秒杀的商品表,来添加秒杀活动的商品信息。

秒杀商品上架:使用定时系统,每天凌晨3点将秒杀的商品上架到redis中,redis设计会使用list存放seckill:sessions:加活动开始时间_结束时间的值,他的值包括活动场次和skuid。由场次_skuid为键将秒杀商品skuid的详细信息存放在hash结构中,键为场次_skuid,值为skuid详细实体信息,并为并在根据场次_skuid生成信号量表示秒杀商品的数量。

随机码的生成作为库存数量锁的信号量的key来访问,只有拥有随机码组合的key才能访问信号量锁才能抢到信号量并减扣库存,否则抢失败。

商品上架线程非安全:假设三台秒杀服务,同时秒杀上架,当多个请求到来时在判断是否上架时在同一时间执行判断没有上架,则都开始上架,导致即便做了去重幂等操作在第一次多线程会导致多次上架,解决使用redisson的锁机制,在上架之前让不同服务的线程竞争同一把锁,谁得到就执行上架,没得到的就会下等待释放后上架,当相同的操作上架由于做了上架幂等,有当前key就放弃上架如下。

  //TODO 保证幂等性问题
    // @Scheduled(cron = "*/5 * * * * ? ")
    @Scheduled(cron = "0 0 1/1 * * ? ")
    public void uploadSeckillSkuLatest3Days() {
        //1、重复上架无需处理
        log.info("上架秒杀的商品...");

        //分布式锁
        RLock lock = redissonClient.getLock(upload_lock);
        try {
            //加锁
            lock.lock(10, TimeUnit.SECONDS);
            seckillService.uploadSeckillSkuLatest3Days();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

通过信号量为每个场次的秒杀数量设置锁功能,而且信号量是和商品上架后就加的,同时做了幂等,只有拿到新号量才真的可以秒杀到商品,在上架的时候会扫近三天的秒杀活动,然后再查skuid信息,完成在redis中上架,上架的时候有随机码,只有活动开始的时候请求才有效。其次有关时间的计算如下,秒杀的核心是避免超卖的现象,这里使用了信号量,只有获得信号量的线程才会往下执行做到了锁的功能。

    private String startTime() {
        LocalDate now = LocalDate.now();
        LocalTime min = LocalTime.MIN;
        LocalDateTime start = LocalDateTime.of(now, min);

        //格式化时间
        String startFormat = start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return startFormat;
    }
    /**
     * 结束时间
     * @return
     */
    private String endTime() {
        LocalDate now = LocalDate.now();
        LocalDate plus = now.plusDays(2);
        LocalTime max = LocalTime.MAX;
        LocalDateTime end = LocalDateTime.of(plus, max);

        //格式化时间
        String endFormat = end.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return endFormat;
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值