PHP Redis Workerman 实现超时取消订单功能
秒杀业务逻辑,多个用户同时抢单,当用户没有支付订单超时时则取消该订单并归还库存
thinkphp redis workerman
1、用户创建订单向redis插入一条订单数据
$redis = new \Redis();
$redis->connect('127.0.0.1',6379);
/**
*列队名称:seckillTime
*到期时间戳:time()+$seckill['payTime']
*订单id:$order->id //可以json字符串存储
*/
$redis->zAdd('seckillTime', time() + $seckill['payTime'], $order->id);
2、workerman 查询这个列队是否有消息,如果有就消费掉
/**
* 启动每个进程
* @param $worker
*/
public function onWorkerStart($worker)
{
date_default_timezone_set('PRC');
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
if($worker->id === 0){
//
}
//秒杀进程
if($worker->id === 1){
echo "启动秒杀任务!\n";
//workerman定时器,每秒执行一次。
Timer::add(1, function() use($redis) {
//通过zRangeByScore查询seckillTime列队中0到当前时间戳的数据。
$res = $redis->zRangeByScore('seckillTime', 0, time());
//存在数据
if (count($res) > 0) {
foreach ($res as $k=>$v){
//处理订单,$res[$k]为生产者存的订单id或数据。
//消费掉列队中的行数据
$redis->zRem('seckill_time', $res[$k]);
}
unset($res);
}
});
}
redis延迟消息列队,将数据存入redis中,workerman出问题掉了,重新启动workerman也可以将没消费的数据消费掉