前言

在商品秒杀活动中,比如商品库存只有100,但是在抢购活动中可能有200人同时抢购,这样就出现了并发,在100件商品下单完成库存为0了还有可能继续下单成功,就出现了超卖。

实现原理

将商品库存从左侧循环lpush添加到num里,然后在下单的时候通过rpop每次从右侧弹出1件商品,当num的值为0时,停止下单。

代码

class Test extends BaseController
{
    public $redis;
    
    public function __construct(){
        //初始化 连接redis
        $this->redis = new \Redis();
        $this->redis->connect('127.0.0.1',6379);
    
    }
    
    //连接redis
    // redis-cli -h 127.0.0.1 -p 6379 
    //apache 模拟高并发 600次请求 每次请求500并发数
    // ab -r -n 600 -c 500  https://******.cn/api/v1/test
    
    /**
     * 测试并发
     */
    public function test()
    {
        $goods_id = 1;
        // halt($this->redis->lrange('num',0,-1));
        $goods = Db::name('redis_goods')->where('id',$goods_id)->find();
        $count=$this->redis->rpop('num');//每次从num取出1
        if($count == 0){
            return "商品已被抢完了";
        }
        $uid = mt_rand(1000,9999);
        $arr = [
            'uid'=>$uid,
            'create_at'=>microtime(),//毫秒时间戳
        ];
        $res = Db::name('redis_data')->insert($arr);
        Db::name('redis_goods')->where('id',$goods_id)->setDec('stock');
        return "ok";
    }

    /**
     *  将商品库存从左侧循环到lpush的num里
     */
    public function ceshi(){
        $goods_id = 1;
        $goods = Db::name('redis_goods')->where('id',$goods_id)->find();
        $num = $this->redis->llen('num');
        $count = $goods['stock']-$num;
        for ($i=1;$i<=$count;$i++){
            //库存循环增加队列
            $this->redis->lpush('num',1);
        }
        return "ok";
    }

文章连接自:https://segmentfault.com/a/1190000020393823


本文由 来鹏飞 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论