PHP【Laravel】delayer基于redis的实现订单超时改变状态

实现这个功能前你需要知道以下,不然可能会比较吃力:
1.服务器的计划任务,shell脚本,或者你有宝塔自带的计划任务会方便很多。
2.有所了解Redis。
3.会写PHP业务逻辑。

好了进入在正题,这里使用一个库delayer。
它是 基于 Redis 的延迟队列中间件,采用 Golang 开发,支持 PHP、Golang 等多种语言客户端。
因此在你的项目中,你需要为PHP装上redis扩展。注意不是Laravel的predis。就是你phpinfo()能看到有redis这个扩展

之后为你的项目加上delayer
你的服务端需要:(就是在服务器中装上delayer,然后在服务器上启动)
https://github.com/mix-basic/delayer
你的客户端需要:(就是在你的项目中装上delayer类库,让你的代码能到delayer的四个基本操作)
https://github.com/mix-basic/delayer-client-php

然后总结一下client这边四个方法:
1.push(放入任务)

//配置好连接redis的信息
$client  = new \Delayer\Client(config('database.redis.default'));

//data为你要存入的数据
$data    = [
      'orderID' => '20181017125789566488854744',
      'action'  => 'close',
 ];
 
 //发送信息
$message = new Message([
 		// 任务ID,必须全局唯一
        'id'    => md5(uniqid(mt_rand(), true)),
        // 主题,取出任务时需使用
        'topic' => 'close_order',
        // 必须转换为string类型
         'body'  => json_encode($data),
]);

/
* push($message, 10, 30)
* 第2个参数为延迟时间,第3个参数为延迟到期后如果任务没有被消费的最大生存时间(秒)
* 延迟时间:参数2设置时间到了才能pop出任务,否则pop返回false;
* 最大生存时间:参数2的时间到之后。倒计时参数3的时间。超时再pop返回false。
*
/
$ret = $client->push($message, 10, 30);
var_dump($ret);

2.pop(取到到期任务)

/
* 配置好连接redis的信息
* 要与Delayer服务器端配置的redis信息相同     
/
$client  = new \Delayer\Client(config('database.redis.default'));
//根据之前的topic值取出最先放入且没有消亡的任务
$message = $client->pop('close_order');

存在则返回如下:
在这里插入图片描述
任务被pop获取一次后就消亡了。再pop的话返回false或者是下一个到期任务。

3.bPop(阻塞取出)

$message = $client->bPop('close_order', 1);//这里相当于1秒后执行pop

4.remove(移除任务)

// push时定义的任务ID
$id = '***';
$ret = $client->remove($id);
var_dump($ret);

移出一个未到期任务。成功true,到期或消亡返回false。

----------------------------------------------以上是delayer的操作说明---------------------------------------------------

下面说明业务逻辑思路:

1.首先在服务器执行计划任务(定时任务)。这里我以宝塔作为例子。如下图:
PHP【Laravel】delayer基于redis的实现订单超时改变状态_第1张图片

shell脚本内容:

step=10 
for (( i = 0; i < 60; i=(i+step) )); do
/www/server/php/73/bin/php /www/wwwroot/phal_admin/autoTask/deal_turn_format_list_result.php
sleep $step 
done
exit 0

脚本说明
step =10 //代表10秒运行一次。
do 路径一(服务器如linux中php的可执行文件) 路径二(PHP的delayer取消订单的业务逻辑)
路径二的示例代码:

pop('close_order');
    if(!$result ){   //服务器一直执行pop,否则break
        break;
    }
    ShopOrder::cancelOrder($result->id); //如果pop到了超时订单就取消订单状态。这里自定义你的业务。
    echo('订单超时取消!');	
}

?>

完成了以上恭喜你基本完成功能的大部分,此时你的服务器已经会自动对你的超时订单进行处理。

2.项目中的业务逻辑
现在服务器已经会对你的超时订单进行处理。
你只需要在未付款订单生成的时候push任务,用户付款的时候remove任务。
下面上伪代码:

未付款订单生成时(push入任务)


$data    = [
      //自定义内容
 ];
 
 //发送信息
$message = new Message([
 		// 任务ID,必须全局唯一,这里可以放订单id(业务中remove需要)
        'id'    => 32,
        // 主题,取出任务时需使用(服务器pop需要)
        'topic' => 'close_order',
        // 必须转换为string类型
         'body'  => json_encode($data),
]);

//放入任务,例如你的需求是30分钟自动取消订单。那么就是1800秒。后面30是消亡时间,自定义。
 push($message, 1800, 30)

用户付款之后(从任务中remove)

$client->remove($id);		//message里你放入的id,如:上面的32

这样一个简单订单超时处理系统算是完成了。

如有不足或错误欢迎指出~

你可能感兴趣的:(PHP)