14

基于Redis的消息队列实现固定库存商品抢购

//商品总库存需要在后台写入到库存队里中,提前写入
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->auth('alloc');
$redis->select(1);
//获取库存并减一写入队列
$k = $redis->lPop('sale_count');
echo $k;
if($k>1){
    if($k-1 == 0){
        $redis->del('sale_count');
    }else{
        $redis->lPush('sale_count',$k-1);
    }
    echo '抢购成功!';
}else{
    echo '售卖完毕!';
}

基于上面的基础解决购买数量存储,超时不支付订单取消订单并恢复库存

<?php
//商品总库存需要在后台写入到库存队里中,提前写入
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('alloc');
$redis->select(1);
//
$user_id = rand(1, 10000);//随机模拟用户ID 不去重复了实际情况下没有重复的
$buy_num = rand(1, 9);//随机模拟购买数量
//获取库存并减一写入队列
$k = $redis->lPop('sale_count');
if ($k > 1) {
    if ($k - $buy_num <= 0) {
        exit('库存不足');
    }else{
        
        $redis->rPush('get_good_list', $user_id);//将抢到顺序插入队列,在守护进程1中处理
        $redis->setex($user_id, 1800, $buy_num);//设置超时时间30分钟
        $redis->rPush('sale_count', $k - $buy_num);
        
    } 
    
    echo '抢购成功!,请五分钟内支付';
} else {
    echo '售卖完毕!';
}
<?php

##Daemon1.php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('alloc');
$redis->select(1);
//while (1){
    $user_id = $redis->lPop('get_good_list');
    if($user_id){
        //获取购买数量
        $buy_num = $redis->get($user_id);
        //创建订单
        $order_no = createOder($user_id,$buy_num);
        //设置订单超时时间
        $redis->setex($order_no,300,1);//5分钟未支付通知Daemon2.php

    }
//}
<?php

#Daemon2.php
ini_set('default_socket_timeout', -1);  //不超时

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('alloc');
$redis->select(1);
//不超时
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
//创建事件监听,__keyevent@1__:expired,数字1代表数据库序号
$redis->psubscribe(array('__keyevent@1__:expired'), 'keyCallback');
// 回调函数,这里写处理逻辑
function keyCallback($redis, $pattern, $chan, $order_no){
    //获取订单信息 获取购买数量
    $buy_num = getOderInfo($order_no);
    //关闭订单
    closeOrder();
    //加入库存
    $redis->rPush('sale_count',$redis->lPop('sale_count')+$buy_num);
}

SmallForest
239 声望12 粉丝

github: