php使⽤redis键空间通知实现定时任务延迟消息队列键空间通知(keyspace notification)
redis实现延迟消息队列
业务场景
1.超时未⽀付⾃动取消订单
2.定时给⽤户推送消息
3.⽂章定时发布
原理:
1.保存数据到redis的时候给键设置过期时间
2.当redis键过期时会给订阅者发送事件消息,
3.在回调事件获取到过期的键名,执⾏定时任务
⽰例
国内php空间
redis配置
修改 f
notify-keyspace-events 的参数为 “Ex”
然后重启redis服务
打开⼀个客户端新增⼀个50秒过期的键
另⼀个客户端设置订阅事件(下图是直接PHP运⾏,客户端执⾏效果⼀样)
具体业务在回调函数⾥处理
⽣产者⽰例
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$redis->select(1);
//创建订单
$order_no = createOder($data);
//设置订单超时时间
$redis->setex($order_no, 300, 1);//5分钟未⽀付通知
消费者
redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$redis->select(1);
//不超时
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
$redis->psubscribe(array('__keyevent@1__:expired'), 'psCallback');
function psCallback($redis, $pattern, $chan, $msg)
{
$orderInfo = Order::getOrderInfo($msg);
if ($orderInfo->pay_status == 0)
//取消订单
}
开启后台驻守执⾏
⽤nohup 命令
nohup php /www/wwwroot/hb/application/common/pusb.php &或者nohup /www/wwwroot/hb/application/common/pusb.php &(不加PHP时 ⽂件⾥需要指定PHP路径)
查看命令是否在后台运⾏
jobs -l  ps -l
杀死进程 kill 进程号
强制杀死 kill -9 pid
附录
redis 类
<?php
class RedisInstance
{
private $redis;
public function __construct($host = '127.0.0.1', $port = 6379)
{
$this->redis = new Redis();
$this->redis->connect($host, $port);
echo "Server is running: " . $this->redis->ping();
}
public function expire($key = null, $time = 0)
{
return $this->redis->expire($key, $time);
}
public function psubscribe($patterns = array(), $callback)
{
$this->redis->psubscribe($patterns, $callback);
}
public function setOption()
{
$this->redis->setOption(\Redis::OPT_READ_TIMEOUT,-1);
}
}
开启事件
<?php
#! /usr/local/php/bin/php
require_once 'RedisInstance.class.php';
require_once 'sql.php';
$redis = new RedisInstance();// 解决Redis客户端订阅时候超时情况
$redis->setOption();
$redis->psubscribe(array('__keyevent@0__:expired'), 'psCallback');
// 回调函数,这⾥写处理逻辑
function psCallback($redis, $pattern, $chan, $msg)
{
$mysql = new sql();
$res = $mysql->go($msg);
print_r($res);
}
键空间通知(keyspace notification)
Note
Warning
键空间通知功能⽬前仍在开发中,这个⽂档所描述的内容,以及功能的具体实现,可能会在未来数周内改变,敬请知悉。功能概览
键空间通知使得客户端可以通过订阅频道或模式, 来接收那些以某种⽅式改动了 Redis 数据集的事件。
以下是⼀些键空间通知发送的事件的例⼦:
所有修改键的命令。
所有接收到  命令的键。
0 号数据库中所有已过期的键。
事件通过 Redis 的订阅与发布功能(pub/sub)来进⾏分发, 因此所有⽀持订阅与发布功能的客户端都可以在⽆须做任何修改的情况下,直接使⽤键空间通知功能。
因为 Redis ⽬前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以如果你的程序需要可靠事件通知(reliable notification of events), 那么⽬前的键空间通知可能并不适合你: 当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件。
未来将会⽀持更可靠的事件分发, 这种⽀持可能会通过让订阅与发布功能本⾝变得更可靠来实现, 也可能会在 Lua 脚本中对消息(message)的订阅与发布进⾏监听, 从⽽实现类似将事件推⼊到列表这样的操作。
事件的类型
对于每个修改数据库的操作,键空间通知都会发送两种不同类型的事件。
⽐如说,对 0 号数据库的键 mykey 执⾏  命令时, 系统将分发两条消息, 相当于执⾏以下两个  命令:
PUBLISH __keyspace@0__:mykey del
PUBLISH __keyevent@0__:del mykey
订阅第⼀个频道 __keyspace@0__:mykey 可以接收 0 号数据库中所有修改键 mykey 的事件, ⽽订阅第⼆个频道 __keyevent@0__:del 则可以接收 0 号数据库中所有执⾏ del 命令的键。
以 keyspace 为前缀的频道被称为键空间通知(key-space notification), ⽽以 keyevent 为前缀的频道则被称为键事件通知(key-event notification)。
当 del mykey 命令执⾏时:
键空间频道的订阅者将接收到被执⾏的事件的名字,在这个例⼦中,就是 del 。
键事件频道的订阅者将接收到被执⾏事件的键的名字,在这个例⼦中,就是 mykey 。
配置
因为开启键空间通知功能需要消耗⼀些 CPU , 所以在默认配置下, 该功能处于关闭状态。
可以通过修改 f ⽂件, 或者直接使⽤ CONFIG SET 命令来开启或关闭键空间通知功能:
当 notify-keyspace-events 选项的参数为空字符串时,功能关闭。
另⼀⽅⾯,当参数不是空字符串时,功能开启。
notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:
字符发送的通知
K键空间通知,所有通知以 __keyspace@<db>__ 为前缀
E键事件通知,所有通知以 __keyevent@<db>__ 为前缀
g DEL 、 EXPIRE 、 RENAME 等类型⽆关的通⽤命令的通知
$字符串命令的通知
l列表命令的通知
s集合命令的通知
h哈希命令的通知

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。