基于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 '售卖完毕!';}
基于上面的基础解决购买数量存储,超时不支付订单取消订单并恢复库存
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 '售卖完毕!';}
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 }//}
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);}