php-redis队列实现抢购商品

公司业务,为了对抗高并发业务,使用redis队列机制,大家可以一起参考参考

1,用户点击某个商品,首先进入的是商品详情页面,这时候我们将商品库存进行入队列

  

private $user_queue_key;
private $goods_number_key;
private $user_id;
private $goods_id;

public function __construct(){
    $this->x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    parent::__construct();
    $goods_id = intval($_GET['goods_id']);
    $area_id  = intval($_GET['area_id']);
    if($goods_id){
        $this->goods_id = $goods_id;
        $this->user_queue_key = "goods_".$goods_id."_user";//当前商品队列的用户情况
        $this->goods_number_key = "goods".$goods_id;//当前商品的库存队列
    }
    $this->user_id = $this->user_id ? $this->user_id : $_SESSION['wap_member_info']['userid'];
}


/*******************判断商品库存够不够,进行队列*************************/
/*******************当天库存数量是否大于当天下单量订单数量******/
$member_id = $this->user_id;
$m     = Model('order');
$redis = new Redis();
$redis->connect(C('redis.master.host'), C("redis.master.port"));
$goods_orders     = $m->getOrderAndOrderGoodsLists($goods_detail['goods_info']['goods_id']);
$order_count      = count($goods_orders);
if($goods_detail['goods_info']['goods_storage'] > $order_count){
    /*队列*/
    $getUserRedis = $redis->hGetAll("{$this->user_queue_key}");
    $gnRedis = $redis->llen("{$this->goods_number_key}");
    /* 如果没有会员进来队列库存 */
    if(!count($getUserRedis) && !$gnRedis){
        for ($i = 0; $i < $goods_detail['goods_info']['goods_storage']; $i ++) {
            $redis->lpush("{$this->goods_number_key}", 1);
        }
    }
    $resetRedis = $redis->llen("{$this->goods_number_key}");
    if(!$resetRedis){
        return callback(false, '系统繁忙,请稍后抢购!');
    }
}else{
    return callback(false, '当前商品已经卖完!');
}
/*******************判断商品库存够不够,进行队列*************************/
/*******************当天库存数量是否大于当天下单量订单数量******/
2,当用户点击立即购买按钮的时候,将该商品用户进行队列

/*******************抢购商品前处理当前会员是否进入队列*************************/
$res = $this->goods_number_queue($result, $member_id);
if($res == 1){
    return callback(false, ',您已进入购买排队,请重试!');
}else{
    /*******************抢购商品前处理当前会员是否进入队列*************************/
    if(!$result['state']){
        return $result;
    }
    //得到页面所需要数据:收货地址、发票、代金券、预存款、商品列表等信息
    $result = $this->getBuyStep1Data($member_id, $result['data']);
    return $result;
}

/**
 * 抢购商品前处理当前会员是否进入队列
 * @access public
 * @author bieanju
 */
public function goods_number_queue($result, $member_id){
    $redis = new Redis();
    $redis->connect(C('redis.master.host'), C("redis.master.port"));
    foreach($result['data']['goods_list'] as $k => $v){
        /*进入队列*/
        $goods_number_key  = "goods" . $v['goods_id'];//当前商品的库存队列
        $user_queue_key    = "goods_" . $v['goods_id'] . "_user";//当前商品队列的用户情况
        $goods_number_keys = $redis->llen("{$goods_number_key}");
        if(!$redis->hGet("{$user_queue_key}", $member_id)){
            $goods_number_keys = $redis->lpop("{$goods_number_key}");
        }
        if($goods_number_keys){
            // 判断用户是否已在队列
            if(!$redis->hGet("{$user_queue_key}", $member_id)){
                // 插入抢购用户信息
                $userinfo = array(
                    "user_id"     => $member_id,
                    "create_time" => time()
                );
                $redis->hSet("{$user_queue_key}", $member_id, serialize($userinfo));
                return 1;
            }else{
                //获取购物车栏
                return 2;
            }
        }else{
            output_error('系统繁忙,请重试!');
        }
    }
}

阅读更多
个人分类: redis
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭