Solo  当前访客:1 开始使用

监听Redis Key过期实现延迟任务队列

Java 有 Quartz 等现成的任务调度框架,但是却不能方便实现一个任务的动态延迟调用,前几天看到Redis的Key过期时间,发现可以监听某一个Key过期,从而实现延迟任务调用。

KeyExpiredListener.java

@Slf4j
public class KeyExpiredListener extends JedisPubSub {

    private TaskHandler taskHandler;

    public KeyExpiredListener (TaskHandler taskHandler) {
        this.taskHandler = taskHandler;
    }

    @Override
    public void onMessage(String channel, String message) {
        try {
            Runnable task = taskHandler.getTaskMap().get(message);
            if (task == null) {
                return;
            }
            taskHandler.getTaskPool().execute(task);
        } catch (Exception e) {
            log.error("调用异常");
        } finally {
            taskHandler.remove(message); //及时释放资源
        }
    }

    @Override
    public void onSubscribe(String channel, int subscribedChannels) {
        log.info("订阅Channel={}", channel);
    }

通过监听key过期,来获取之前缓存在内存中的Runnable,再放入线程池中调用。

TaskHandler

@Data
public class TaskHandler {
    private ExecutorService taskPool;

    private ConcurrentHashMap<String, Runnable> taskMap = new ConcurrentHashMap<>();

    public TaskHandler() {
        this.taskPool = Executors.newCachedThreadPool();
    }

    public TaskHandler(ExecutorService executorService) {
        this.taskPool = executorService;
    }

    /**
     * 增加延迟任务
     * @param key
     * @param delayTime
     * @param task
     */
    public void add(String key, Integer delayTime, Runnable task) {
        // 写入过期Key
        Jedis.getInstance().getResource().setex(key, delayTime, "");

        this.taskMap.put(key, task);
    }

    /**
     * 释放资源
     * @param key
     */
    public void remove(String key) {
        Jedis.getInstance().getResource().del(key);
        this.taskMap.remove(key);
    }
}

通过一个Map来缓存Key与Runnable之间的关系,往Redis中插入一个带过期时间(delayTime参数)的记录。

具体代码

https://github.com/wellCh4n/Redis-Schedule

尾巴

如果想放在SpringBoot项目中使用,只要新建一个Bean,自己创建线程池,通过Schedule的构造方法中即可。
新增任务调用 Schedule中的add()方法,移除任务调用remove()方法。
具体可以查看Main.java里面的例子。


标题:监听Redis Key过期实现延迟任务队列
作者:wellCh4n
地址:http://www.wellch4n.com/articles/2019/09/05/1567678402206.html

wellCh4n
wellCh4n @ Estelle925 • 19-09-05 18:26 • Reply

这也太水了8

Estelle925
Estelle925 • 19-09-05 18:23 • Reply

第一个评论,不用感谢。😁