当前位置:首页 > PHP >

用PHP+Redis实现延迟任务,实现实现自动取消订单,自动完成订单等功能

时间:2023-03-17 00:37:15浏览:8060 转载

业务场景: 当一个业务触发以后需要启动一个定时任务,在指定时间内再去执行一个任务(如自动取消订单,自动完成订单等功能)


解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本以上;redis的keyspace notifications 会在key失效后发送一个事件,监听此事件的的客户端就可以收到通知


服务准备:
修改reids配置文件(redis.conf)【window系统配置文件为:redis.windows.conf 】
redis默认不会开启keyspace notifications,因为开启后会对cpu有消耗
php要安装先redis扩展


以宝塔中安装的Redis为例,大约在1062行


原配置为:
notify-keyspace-events ""
更改 配置如下:
notify-keyspace-events "Ex"
保存配置后,重启Redis服务,使配置生效


开始编码,3个文件实现,配置文件一个,订阅和发布各一个:


1、配置文件Config_Redis.inc.php

connect(CFG_Redis_Server,6379) or die ("could net connect redis server");
if(strlen(CFG_RedisDBPass)>0){
    $redis->auth(CFG_RedisDBPass);
}
if(intval(CFG_RedisDBNum)>0){
    $redis->select(CFG_RedisDBNum);
}


2、发布文件publish.php

setex(CFG_REDISPRE.$key,$RandSecond,'redis延迟任务');      //X秒后回调
echo $QueueID.PHP_EOL;

3、订阅文件subscribe.php

setOption(Redis::OPT_READ_TIMEOUT, -1);

// 当key过期的时候就看到通知,订阅的key __keyevent@__:expired 
// 这个格式是固定的,db代表的是数据库的编号,由于订阅开启之后这个库的所有key过期时间都会被推送过来,所以最好单独使用一个数据库来进行隔离
$redis->psubscribe(array('__keyevent@'.CFG_RedisDBNum.'__:expired'), 'keyCallback');
// 回调函数,这里写处理逻辑
function keyCallback($redis, $pattern, $channel, $msg)
{
    echo PHP_EOL;
    echo "Pattern: $pattern\n";
    echo "Channel: $channel\n";
    echo "Payload: $msg\n\n";
    $list = explode('|',$msg);

    $QueueID = isset($list[0])?$list[0]:'0';
    $DoURL = isset($list[1])?$list[1]:'0';
    echo $QueueID.PHP_EOL;
    echo $DoURL.PHP_EOL;
    file_get_contents($DoURL."?ID=".$QueueID);
}


注意事项:

1、监听消息事件触发是发送给所有监听者的,所以在多监听者的时候需要做一个redis分布式锁,保证失效消息不要重复被消费。
2、此监听是redis中所有的消息失效都会触发,所以要进行key值的过滤,来过滤出我们需要处理的消息,本例子是用|来分隔右边的为执行URL,有URL才执行


订阅页面一定要用cli模式,直接在shell里执行 php /www/subscribe.php

实际应用时这个可以挂起的方式执行

挂起执行方式参考:Linux上实现秒级执行的定时任务 https://www.bluecode.cn/show-542.html


亲测能用!



上一篇:利用python将redis中的一个db库转移到另一个db库
下一篇:Linux系统如何设置开机自动运行脚本?

发表评论

昵称:  验证码:

关于博主

博主

博主:BlueCode

职业:web程序

简介:2002年开始一直从事Web制作,网站运营,会PHP+MYSQL ASP+MSSQL,微信开发