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 做消息队列

php项目需要一个消息队列,最后为了简单选择了Redis List..在Redis服务器已经启动的前提下.1. 连接Redis$redis = new Redis(); $redis->connect...
  • zhao0829wang
  • zhao0829wang
  • 2015年05月25日 16:15
  • 8874

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

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

PHP用redis实现多进程队列

PHP用redis实现多进程队列
  • lqy5589731
  • lqy5589731
  • 2016年04月08日 17:10
  • 2034

PHP中利用redis实现消息队列处理高并发请求

将请求存入redis 为了模拟多个用户的请求,使用一个for循环替代 //redis数据入队操作 $redis = new Redis(); $redis->connect('127.0.0.1'...
  • moliyiran
  • moliyiran
  • 2017年11月09日 21:25
  • 524

PHP - Redis队列解决执行速度问题

今天优化了一个用Redis队列异步解决了提交数据反映时间慢点问题 整理下和大家分享下 一是怕自己忘了 二是希望可以帮助到你们 或多或少提供些思想也是好的...    先看下图,在没有优化之前一起提交五...
  • xuezhiwu001
  • xuezhiwu001
  • 2016年10月25日 23:09
  • 1546

php使用redis作为消息队列

安装redisredis不在centos官方源里面,需要手动下载EPEL(Extra Packages for Enterprise Linux)进行安装。 EPEL相当于是原来源的扩展,具体的介绍...
  • koastal
  • koastal
  • 2016年10月14日 10:26
  • 7214

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

【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合 https://segmentfault.com/a/1190000004136250 PH...
  • liuxiaojun828
  • liuxiaojun828
  • 2016年07月06日 14:49
  • 3629

redis 队列操作的例子(php)

Reids是一个比较高级的开源key-value存储系统,采用ANSI C实现。其与memcached类似,但是支持持久化数据存储 入队操作  复制...
  • cloverphp
  • cloverphp
  • 2014年10月08日 17:57
  • 1867

基于redis+mysql+php的简单队列实现

消息队列在是分布式系统中必不可少的中间件,目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,Kafka,RocketMQ等。然而对于一个要求不高的小型系统来说,单独使用维护这些队...
  • itest_2016
  • itest_2016
  • 2017年07月25日 13:23
  • 779

php 实现 redis 队列,等待有新消息入列

1. 消息入列代码, t1.php: $redis = new Redis(); $redis->connect('127.0.0.1', 6379); while(1){ try...
  • wang350
  • wang350
  • 2016年01月20日 18:52
  • 2494
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:php-redis队列实现抢购商品
举报原因:
原因补充:

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