网站首页 文章专栏 利用redis实现 限时秒杀

利用redis实现 限时秒杀

编辑时间:2019-09-29 14:50:53 作者:苹果 浏览量:2235


    前言:应用场景:一批商品,限时秒杀



常规做法:
//连接数据库或缓存,查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数,因为有可能在剩余一件时,同时过来两个请求。


建议做法:

基于单线程处理思想。一个个验证,即使有很多用户同时发送请求,也是一个个检查并给与抢购资格,一旦库存抢尽,后面的用户就无法继续了。之后我们再引导这些用户去完成订单的其他步骤,到这里才涉及到与数据库的交互。


  1. 建立秒杀商品时,立即建立对应的缓存仓库


        public function     setredis(){
            $limit=20;  //上限总数
            $goods_id=1001; //商品ID
            $finish_time='2019-10-8 00:00:00'; //活动结束时间
            $reids_expire=strtotime($finish_time)-time();
        
            $reids_key='goods_limits_'.$goods_id;
        
            $len=$this->redis->llen($reids_key);  //获取上次活动剩余的库存   一般为0
            $num=$limit-$len;// 这次需要追加的数量
            for ($i=1;$i<=$num;$i++){
                $this->redis->lpush($reids_key,$i);     //生成一个总库存列表
            }
        
            if($this->redis->llen($reids_key)==$limit){
                $this->redis->expire($reids_key,$reids_expire+3600); //习惯给过期时间多设置比时间长一点
                return true;
            }
        
            return false;
        }



    2.用户发起请求,验证

        public function    check($goods_id){
            $reids_key='goods_limits_'.$goods_id;
            $uid=session('uid');
            $last_time=$this->redis->ttl($reids_key);
            if(!$last_time){
                return ['msg'=>'已过期','status'=>-200];
            }
            $check=$this->redis->lpop($reids_key);
            if(!$check){
                return ['msg'=>'该商品已被抢完','status'=>-200];
            }
        
            $goods_snag_key='goods_snag_'.$goods_id.'_'.$uid;
            $this->redis->INCR($goods_snag_key,$last_time+3600); //用户购买这件商品数量,用于判断 限制用户购买数量,无需要,可省略
            return ['msg'=>'抢到了,请继续后续处理','status'=>200];
        }



    出自:何冰华个人网站

    地址:https://www.hebinghua.com/

    转载请注明出处


来说两句吧
最新评论
  • 何冰华个人网站
    胖虎 2020-06-18 00:31:47
    Php?