实现这个功能前你需要知道以下,不然可能会比较吃力:
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);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2.pop(取到到期任务)

/
* 配置好连接redis的信息
* 要与Delayer服务器端配置的redis信息相同
/
$client = new \Delayer\Client(config('database.redis.default'));
//根据之前的topic值取出最先放入且没有消亡的任务
$message = $client->pop('close_order');
1
2
3
4
5
6
7
存在则返回如下:

任务被pop获取一次后就消亡了。再pop的话返回false或者是下一个到期任务。

3.bPop(阻塞取出)

$message = $client->bPop('close_order', 1);//这里相当于1秒后执行pop
1
4.remove(移除任务)

// push时定义的任务ID
$id = '***';
$ret = $client->remove($id);
var_dump($ret);
1
2
3
4
移出一个未到期任务。成功true,到期或消亡返回false。

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

下面说明业务逻辑思路:

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
1
2
3
4
5
6
脚本说明
step =10 //代表10秒运行一次。
do 路径一(服务器如linux中php的可执行文件) 路径二(PHP的delayer取消订单的业务逻辑)
路径二的示例代码:

<?php
use App\Models\ShopOrder; //你的订单模型
use Delayer\Client; //delayer

require '/home/vagrant/code/public/init.php'; //必须项目入口文件,我这里是laravel

$client = new \Delayer\Client(config('database.redis.default')); //配置参数,不明白说明你没好好看

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

?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
完成了以上恭喜你基本完成功能的大部分,此时你的服务器已经会自动对你的超时订单进行处理。

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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
用户付款之后(从任务中remove)

$client->remove($id); //message里你放入的id,如:上面的32
1
这样一个简单订单超时处理系统算是完成了。

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

PHP【Laravel】delayer基于redis的实现订单超时改变状态的更多相关文章

  1. Delayer 基于 Redis 的延迟消息队列中间件

    Delayer 基于 Redis 的延迟消息队列中间件,采用 Golang 开发,支持 PHP.Golang 等多种语言客户端. 参考 有赞延迟队列设计 中的部分设计,优化后实现. 项目链接:http ...

  2. Matching Engine For Laravel(基于redis的撮合引擎),PHP高性能撮合引擎

    Laravel Package for Matching Engine 快速开始 github地址 安装: composer require sting_bo/mengine 复制配置文件: php ...

  3. 基于 Redis 生成分布式订单号

    环境依赖: //spingBoot <version>2.6.6</version> //jdk11 <dependency> <groupId>org ...

  4. 基于redis的订单号生成方案

    目前,比较火的nosql数据库,如MongoDB,Redis,Riak都提供了类似incr原子行操作. 下面是PHP版的一种实现方式: <?php /** * 基于Redis的全局订单号id * ...

  5. [原创]Laravel 基于redis队列的解析

    目录 参考链接 本文环境 为什么使用队列 Laravel 中的队列 分发任务 任务队列 Worker Last-Modified: 2019年5月10日11:44:18 参考链接 使用 Laravel ...

  6. [转载] 基于Redis实现分布式消息队列

    转载自http://www.linuxidc.com/Linux/2015-05/117661.htm 1.为什么需要消息队列?当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消 ...

  7. Spring+Shiro搭建基于Redis的分布式权限系统(有实例)

    摘要: 简单介绍使用Spring+Shiro搭建基于Redis的分布式权限系统. 这篇主要介绍Shiro如何与redis结合搭建分布式权限系统,至于如何使用和配置Shiro就不多说了.完整实例下载地址 ...

  8. 基于Redis实现延时队列服务

    背景 在业务发展过程中,会出现一些需要延时处理的场景,比如: a.订单下单之后超过30分钟用户未支付,需要取消订单 b.订单一些评论,如果48h用户未对商家评论,系统会自动产生一条默认评论 c.点我达 ...

  9. 【转】基于Redis实现延时队列服务

    背景 在业务发展过程中,会出现一些需要延时处理的场景,比如: a.订单下单之后超过30分钟用户未支付,需要取消订单b.订单一些评论,如果48h用户未对商家评论,系统会自动产生一条默认评论c.点我达订单 ...

随机推荐

  1. 网络协议之mDNS

    DNS(Domain Name System,域名系统)因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串.通过主机名,最终得 ...

  2. 某些 UI效果 实现思路

    一.日历组件: https://blog.csdn.net/amork/article/details/7257212 二.瀑布流 三.轮播图:轮播图已经用的很多了,结构也简单就不去将了. 四.分页组 ...

  3. NOIP 历年试题大致考点总结

    总的来说,水平还不够-- 要努力了! NOIP2012 D1T1 模拟, 字符串 D1T2 贪心, 数学 (推导贪心策略), 高精度 D1T3 unsolved 开车旅行 倍增 D2T1 解线性模方程 ...

  4. HDU 3183 A Magic Lamp(RMQ问题, ST算法)

    原题目 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. sudo su 和sudo -s的区别

    sudo su 和 sudo -s都是切换到root用户,不同的是: sudo su 环境用的是目标用户(root)的环境 sudo -s 环境用的是当前用户本身的环境

  6. codeforces gym 100345I Segment Transformations [想法题]

    题意简述 给定一个由A C G T四个字母组成的密码锁(每拨动一次 A变C C变G G变T T变A) 密码锁有n位 规定每次操作可以选取连续的一段拨动1~3次 问最少几次操作可以将初始状态变到末状态 ...

  7. python接口自动化测试三十六:数据驱动参数化之paramunittest

    官方文档1.官方文档地址:https://pypi.python.org/pypi/ParamUnittest/2.github源码下载地址:https://github.com/rik0/Param ...

  8. hbase之RPC详解

    Hbase的RPC主要由HBaseRPC.RpcEngine.HBaseClient.HBaseServer.VersionedProtocol 5个概念组成. 1.HBaseRPC是hbase RP ...

  9. 8条关于Web前端性能的优化建议

    一般网站优化都是优化后台,如接口的响应时间.SQL优化.后台代码性能优化.服务器优化等.高并发情况下,对前端web优化也是非常重要的. 下面说说几种常见的优化措施. 1.HTML CSS JS位置 一 ...

  10. 【BZOJ2138】stone

    题目 好厉害的题啊 这道题不难看成一个二分图模型,但是给人一种求最大匹配的感觉,这实在不是很好求的样子,于是自闭了 但是不妨这样来考虑,对于一个需求\(k_i\),我们求一个最大的\(x\leq k_ ...