基于Redis的定时任务

原创
2017/05/26 19:03
阅读数 2.2W

基于Redis的定时任务

最近遇到一个业务场景,某次活动开始后要在250秒后自动关闭,然后修改活动的状态。考虑一下可以用传统的定时任务去处理

  • 会出现250秒时间的延时问题,比如某次任务刚刚结束,但是定时任务在前一秒就结束了,那么活动虽然结束了,那么还要再等一个定时任务才能执行,时效性不行。

针对这个业务需求,我们采用 Redis (2.8.0+版本)的订阅发布模式 ,当key过期时触发相关事件。

redis配置

Redis 配置文件的具体配置:

#
#  Example 2: to get the stream of the expired keys subscribing to channel
#  获取订阅channel的过期的key
#  channel名称: __keyevent@0__:expired 
#
notify-keyspace-events Ex
#
#  By default all notifications are disabled because most users don't need
#  this feature and the feature has some overhead. Note that if you don't
#  specify at least one of K or E, no events will be delivered.
#  默认情况下,所有通知都被禁用,因为大多数用户不需要这个功能和功能有一些开销
#  请注意,如果没有指定K或E中的至少一个,不会传送任何事件。
#
#  notify-keyspace-events ""

redis.conf 的配置如上,我也加上了相关注释。

jfinal配置

public class LmsCoreConfig extends JFinalConfig {
 
    /**
     * 启动后回调,使用异步,不然线程阻塞
     */
    public void afterJFinalStart() {
        FutureTask futureTask = new FutureTask(() -> {
            Redis.use().getJedis().subscribe(new KeyExpiredListener(), "__keyevent@0__:expired");
            return null;
        });
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        executorService.submit(futureTask);
    }

}

/**
*  监听redis key过期的监听器
*/
public class KeyExpiredListener extends JedisPubSub {
    @Override
    public void onMessage(String channel, String message) {
        // message 对应 key值
        //TODO key过期后的业务代码。
    }
}


测试

我们通过redis-cli  设置几个有过期时间的key测试一下

127.0.0.1:6379> SET test 123
OK
127.0.0.1:6379> EXPIRE test 60
(integer) 1

60秒触发KeyExpiredListener监听器

展开阅读全文
加载中
点击加入讨论🔥(2) 发布并加入讨论🔥
打赏
2 评论
56 收藏
4
分享
返回顶部
顶部