前言:
之前,在折腾的小项目里用到一个计时器的项目。背景:订单在20min后若没有被答复,实现一个推送事件。之前准备用cron模块,后来发现模块可能达不到要求,需要多个实例,而且不能销毁上一个实例(终止计时)。接下来看一下geemo抄别的博客大神的背景。
本文所说的定时任务或者说计划任务并不是很多人想象中的那样,比如说每天凌晨三点自动运行起来跑一个脚本。这种都已经烂大街了,随便一个 Crontab 就能搞定了。
这里所说的定时任务可以说是计时器任务,比如说用户触发了某个动作,那么从这个点开始过二十四小时我们要对这个动作做点什么。那么如果有 1000 个用户触发了这个动作,就会有 1000 个定时任务。于是这就不是 Cron 范畴里面的内容了。
举个最简单的例子,一个用户推荐了另一个用户,我们定一个二十四小时之后的任务,看看被推荐的用户有没有来注册,如果没注册就给他搞一条短信过去。
每错,不要脸的Geemo原封不动的抄了下来。因为小项目里用到Redis,当时就想到了TTL,然而当时就看到了notify-keyspace-events 键事件通知,一眼过了,因为貌似实现起来很复杂。最后准备其实直接cron即可(PS:感觉一定会卡死,后来考虑用lua脚本嵌入redis计时+Blpop)。几天前,逛geemo博客时候看到他的《Node.js 中使用 Redis 来实现定时任务》,仔细读了读,思路原来如此简单。
正文:
具体请大家移步: Geemo狗的博客《Node.js 中使用 Redis 来实现定时任务》。
那么我做一下补充和理解。如果使用psubscribe命令 ——all in the memory 随你折腾了思密达。
var Redis=require('redis'); var subscriberClient = Redis.createClient(6379,'localhost'); subscriberClient.on("error", (error) =>{ throw new Error(`Redis hsa an error—${error.message}`); }); //psubscribe version>2.0 订阅一个或多个频道 subscriberClient.psubscribe('__keyevent@' + 1 +'__:expired'); subscriberClient.on("pmessage", function (pattern, channel, expiredKey) { console.log(channel, expiredKey) } )
另外订阅只能返回键名,所以键名需要包含众多的信息,如 uuid:option@phone,在事件通知后解析键名即可。
这样就简单的实现了,定时任务,而且也不必耗费太大的系统资源,设置TTL后会自动销毁,也非常方便,也不用在开发过程中,不断的刷脚本了。