Redis是一个开源且支持持久化的Key-Value内存数据库,功能相当强大,用起来也简单,笔者几乎每个项目都会用到,
不过今天要说的是大家平常不怎么用到的"超时监听"。
"超时监听",顾名思义当某个Key值过期时,便会触发相应的事件,过期事件是通过Redis的订阅与发布功能(pub/sub)来进行分发,需要详细了解的朋友可以百度一下。
常规的事件,需要先发布相应的事件,然后在订阅,但key值超时不需要自己发布,只需要修改redis配置文件redis.conf:
找到 ”notify-keyspace-events Ex",将改行的注释去掉,如下图:
然后保存,重启redis,之后redis会对设置了expire的数据进行监听。
关于redis的事做完了,接下来的就是应用了,笔者今天选择的是NodeJS,其他语言大同小异。
首先,需要安装redis,用npm就可以,然后连接redis,并且绑定过期redis回调函数。
注:以下JS代码都是基于ES6的。
let pub = redis.createClient(6380);
pub.send_command('config', ['set', 'notify-keyspace-events', 'Ex'], SubscribeExpired);
这样就接收了redis的key过期事件,下一步实现回调函数SubscribeExpired。
function SubscribeExpired(e, r) {
let sub = redis.createClient(6380);
const expired_subKey = '__keyevent@0__:expired';
sub.subscribe(expired_subKey, function () {
sub.on('message', function (chan, msg) {
//msg就是过期的key值,由于过期了,所有回调时只有key值
//相应的处理代码
});
})
}
机制讲完了,由于过期之后只会回调key值,因此,我们需要的数据只能存在key里面。
下面笔者和大家分享一个此机制的应用场景:
微信公众号红包超时退回
笔者有些游戏项目里面有红包机制,就是玩家达到某些条件,就可以领取红包,红包累计到一定数额就可以以公众号红包的形式发送给玩家,但是微信红包有一个24小时未领取则会自动退回原账户,但是这个退回并没有回调事件,也就是说我们的系统不知道,微信有提供一个查询红包状态的接口,如何将超时的红包退回玩家在游戏的账户,我们就想到了redis的key过期机制。
实现方式如下:
每当有用户提现到红包时,就往redis里面写一条数据,key为用户ID加上红包ID,value值为空,同时设置该key过期事件为24小时;
然后添加过期回调事件,
回调事件处理如下:
从超时的key里面提取出对应的玩家ID和红包ID,调用微信的接口查询该红包的状态,看是被领取还是超时退回(正常只有这两个状态,不然就是异常了),超时退回就将对应的红包金额退回到玩家游戏账户。
以上功能笔者都是代码亲测,大家可以参考一下。