php-redis队列实现抢购商品

原创 2017年06月14日 09:17:50

公司业务,为了对抗高并发业务,使用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('系统繁忙,请重试!');
        }
    }
}

相关文章推荐

php结合redis实现高并发下的抢购、秒杀功能

抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到用缓存来处理抢购,避...
  • nuli888
  • nuli888
  • 2016年07月09日 10:09
  • 32717

php结合redis实现高并发下的抢购、秒杀功能

*原文地址: http://blog.csdn.net/nuli888/article/details/51865401 抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: ...
  • lmjy102
  • lmjy102
  • 2017年04月10日 16:12
  • 389

【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合 PHP解决抢购、秒杀

【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合 https://segmentfault.com/a/1190000004136250 PH...

php结合redis实现高并发下的抢购、秒杀功能

抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到用缓存来处理抢购,避...

php结合redis实现高并发下的抢购、秒杀功能

转自http://blog.csdn.net/nuli888/article/details/51865401 抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生...

php结合redis实现高并发下的抢购、秒杀功能

抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到用缓存来处理抢...

php+redis消息队列抢购实现

【高并发简单解决方案】redis队列缓存 + 批量入库 + php离线整合

需求背景:有个 调用统计日志存储和统计需求 ,要求存储到mysql中;存储数据高峰能达到日均千万,瓶颈在于 直接入库并发太高,可能会把mysql干垮 。 问题分析 思考:应用网站架构的衍化过程中,...

使用 redis 减少 秒杀库存 超卖思路

由于数据库查询的及插入的操作 耗费的实际时间要耗费比redis 要多, 导致 多人查询时库存有,但是实际插入数据库时却超卖 redis 会有效的减少相关的延时,对于并发量相对较少的 可以一用 ...

通过请求队列的方式来缓解高并发抢购(初探)

通过请求队列的方式来缓解高并发抢购(初探)  原文:http://www.cnblogs.com/XiaoyangBoke/p/6701780.html 一、背景        在移动互联网高速...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:php-redis队列实现抢购商品
举报原因:
原因补充:

(最多只允许输入30个字)