软件版本
redis: 4.0.10
php:7.1
redis缓存拥有TTL特性,这个到时间删除缓存数据的特性可以运用到诸多场景,比如:客户下单后半小时不支付自动取消订单,订单完成后几天自动好评,挂机任务完成后发送通知等等。比较普通的方法是创建提个crontab定时检查,但是这个方法时效性会有误差,而且每次任务执行都要查询数据,无形中增加了许多无用数据库压力。所以,我们可以选择更好的方法,利用redis的订阅/发布的模式,事件发生时存入redis并设置时间,到点时监控expired事件即可。
操作步骤:
1、修改redis.conf
#打开以下注释,并注意config文件有没重复定义变量(我就是被这点搞了很久)
notify-keyspace-events Ex
2、启动redis-server
redis-server /redis.conf
3、订阅监听expired时间
#redis-cli命令行中实现
127.0.0.1:6379> PSUBSCRIBE __keyevent@*__:expired
#php-cli实现
#命令行中cli模式执行以下文件
<?php
require_once 'Redis.class.php';
$redis = new \RedisClass();
// 解决Redis客户端订阅时候超时情况
$redis->setOption();
$redis->psubscribe(array('__keyevent@0__:expired'), 'keyCallback');
// 回调函数,这里写处理逻辑
function keyCallback($redis, $pattern, $chan, $msg)
{
echo "Pattern: $pattern\n";
echo "Channel: $chan\n";
echo "Payload: $msg\n\n";
}
4、测试
#redis-cli命令行中实现
127.0.0.1:6379> set tesst11 asd ex 10
#php-fpm实现
<?php
require_once './Redis.class.php';
$redis = new \RedisClass();
$order_id = 123;
$redis->setex('order_id233',10,$order_id);
5、附件、redis操作类
<?php
class RedisClass
{
private $redis;
public function __construct($host = '127.0.0.1', $port = 6379)
{
$this->redis = new Redis();
$this->redis->connect($host, $port);
}
public function setex($key, $time, $val)
{
return $this->redis->setex($key, $time, $val);
}
public function set($key, $val)
{
return $this->redis->set($key, $val);
}
public function get($key)
{
return $this->redis->get($key);
}
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);
}
}
总结:
然后我们就可以通过定义不同类型key代表不同的业务场景,在subscribe中高效且优雅地处理各种业务。