使用PHP+Redis实现延迟任务,实现自动取消订单功能(3)
window系统测试方法:先在cmd命令界面运行psubscribe.php,然后网页打开index.php。
使监听后台始终运行(订阅)
有个问题 做到这一步,利用 phpredis 扩展,成功在代码里实现对过期 Key 的监听,并在 psCallback()里进行回调处理。开头提出的两个需求已经实现。可是这里有个问题:redis 在执行完订阅操作后,终端进入阻塞状态,需要一直挂在那。且此订阅脚本需要人为在命令行执行,不符合实际需求。
实际上,我们对过期监听回调的需求,是希望它像守护进程一样,在后台运行,当有过期事件的消息时,触发回调函数。使监听后台始终运行 希望像守护进程一样在后台一样,
我是这样实现的。
Linux中有一个nohup命令。功能就是不挂断地运行命令。同时nohup把脚本程序的所有输出,都放到当前目录的nohup.out文件中,如果文件不可写,则放到<用户主目录>/nohup.out 文件中。那么有了这个命令以后,不管我们终端窗口是否关闭,都能够让我们的php脚本一直运行。
编写psubscribe.php文件:
<?php #! /usr/bin/env php ini_set('default_socket_timeout', -1); //不超时 require_once 'Redis2.class.php'; $redis_db = '15'; $redis = new \Redis2('127.0.0.1','6379','',$redis_db); // 解决Redis客户端订阅时候超时情况 $redis->setOption(); //当key过期的时候就看到通知,订阅的key __keyevent@<db>__:expired 这个格式是固定的,db代表的是数据库的编号,由于订阅开启之后这个库的所有key过期时间都会被推送过来,所以最好单独使用一个数据库来进行隔离 $redis->psubscribe(array('__keyevent@'.$redis_db.'__: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); $order_sn = isset($list[0])?$list[0]:'0'; $use_mysql = isset($list[1])?$list[1]:'0'; if($use_mysql == 1){ require_once 'db.class.php'; $mysql = new \mysql(); $mysql->connect(); $where = "ordersn = '".$order_sn."'"; $mysql->select('order','',$where); $finds=$mysql->fetchAll(); print_r($finds); if(isset($finds[0]['status']) && $finds[0]['status']==0){ $data = array('status' => 3); $where = " id = ".$finds[0]['id']; $mysql->update('order',$data,$where); } } } //或者 /*$redis->psubscribe(array('__keyevent@'.$redis_db.'__:expired'), function ($redis, $pattern, $channel, $msg){ echo PHP_EOL; echo "Pattern: $pattern\n"; echo "Channel: $channel\n"; echo "Payload: $msg\n\n"; //................ });*/
注意:我们在开头,申明 php 编译器的路径:
#! /usr/bin/env php
内容版权声明:除非注明,否则皆为本站原创文章。