广告位联系
返回顶部
分享到

Redis模拟延时队列实现日程提醒的方法

Redis 来源:互联网 作者:佚名 发布时间:2024-11-23 08:59:35 人浏览
摘要

使用Redis模拟延时队列 实际上通过MQ实现延时队列更加方便,只是在实际业务中种种原因导致最终选择使用redis作为该业务实现的中间件,顺便记录一下。 该业务是用于日程短信提醒,用户添加

使用Redis模拟延时队列

实际上通过MQ实现延时队列更加方便,只是在实际业务中种种原因导致最终选择使用redis作为该业务实现的中间件,顺便记录一下。
该业务是用于日程短信提醒,用户添加日程后,就会被放入redis队列中等待被执行发送短信提醒业务。
本文介绍如何使用Redis来实现一个简单的延时任务队列,通过这个示例,可以帮助你理解如何利用Redis的有序集合特性来管理和执行延时任务。

设计思路

Redis有序集合(Sorted Set)可以很好地用来实现延时队列的功能。通过将任务的执行时间作为分数(score)来存入有序集合中,并定期检查集合中小于等于当前时间的任务来触发执行。

代码实现

JedisCluster连接初始化

首先,我们需要初始化JedisCluster连接来与Redis集群进行交互。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

private static final String ZSET_KEY = "sms_delayed_tasks";

private JedisCluster jedisCluster;

public void RedisClusterScheduler() {

    Set<HostAndPort> nodes = new HashSet<>();

    //从配置文件中读取redis集群配置

    for (String node : AcpCore.getProp("spring.redis.cluster.nodes").split(",")) {

        String[] hostPort = node.split(":");

        nodes.add(new HostAndPort(hostPort[0], Integer.parseInt(hostPort[1])));

    }

    GenericObjectPoolConfig<Jedis> poolConfig = new GenericObjectPoolConfig<>();

    poolConfig.setMaxTotal(128);

    poolConfig.setMaxIdle(128);

    poolConfig.setMinIdle(16);

    jedisCluster = new JedisCluster(nodes, 2000, 2000, 5, AcpCore.getProp("spring.redis.password"), poolConfig);

    if (!isCalled) {

        isCalled = true;

        startTaskChecker();

    }

}

添加延时任务

我们可以通过指定任务和执行时间来添加延时任务。该方法将执行时间转换为时间戳,并将任务存储在Redis有序集合中。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public void addDelayedTask(String task, String time) {

    long executeTime = convertToTimestamp(time);

    if (executeTime > System.currentTimeMillis() / 1000) {

        jedisCluster.zadd(ZSET_KEY, executeTime, task);

        log.info("添加任务: " + task + " 执行时间: " + executeTime);

    } else {

        log.info("任务时间必须在当前时间之后: " + task);

    }

}

private long convertToTimestamp(String time) {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    try {

        return sdf.parse(time).getTime() / 1000;

    } catch (ParseException e) {

        e.printStackTrace();

        return System.currentTimeMillis() / 1000;

    }

}

检查和执行任务

通过一个定时任务不断检查当前时间之前的任务并执行。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

private void startTaskChecker() {

    executorService.submit(() -> {

        while (!Thread.currentThread().isInterrupted()) {

            try {

                checkAndExecuteTasks();

                Thread.sleep(1000);

            } catch (Exception e) {

                log.info(new Date() + "发生异常但不中断,异常是:" + e);

            }

        }

    });

}

private void checkAndExecuteTasks() {

    long currentTime = System.currentTimeMillis() / 1000;

    Set<String> tasks = jedisCluster.zrangeByScore(ZSET_KEY, 0, currentTime);

    for (String task : tasks) {

        jedisCluster.zrem(ZSET_KEY, task);

        executeTask(task);

    }

}

执行任务的逻辑

假设任务内容是一个JSON对象,执行逻辑在这里可以是任何操作,比如调用外部服务、发送消息等。

1

2

3

4

5

private void executeTask(String taskJson) {

    JSONObject task = JSONObject.parseObject(taskJson);

    // 在此处添加具体的业务逻辑

    log.info("执行任务: " + task);

}

总结

通过Redis的有序集合和简单的定时器,能够实现一个简洁有效的延时任务队列。
当然,这个示例是一个简化的模型,在生产环境中,你需要考虑任务的幂等性、系统崩溃后的恢复策略、任务的优先级等问题。希望本文能为你提供实现延时队列的思路和参考。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • mysql中窗口函数lag()用法介绍
    在MySQL中,窗口函数LAG()可以用来访问当前行的前一行或多行的数据。这个函数通常用于分析时间序列数据,比如计算相邻行之间的差异或者
  • MySQL中group_concat函数用法小结

    MySQL中group_concat函数用法小结
    一、group_concat函数的功能 将group by产生的同一个分组中的值连接起来,返回一个字符串结果。group_concat函数首先根据group by指定的列进行分组
  • Redis模拟延时队列实现日程提醒的方法
    使用Redis模拟延时队列 实际上通过MQ实现延时队列更加方便,只是在实际业务中种种原因导致最终选择使用redis作为该业务实现的中间件,顺
  • mysql日常锁表之flush_tables介绍
    1. Flush tables简介 官方手册中关于Flush tables的介绍 Closes all open tables, forces all tables in use to be closed, and flushes the query cache. FLUSH TABLES also remove
  • Mysql中的secure_file_priv参数设置方法

    Mysql中的secure_file_priv参数设置方法
    secure_file_priv是MySQL中的系统变量,用于限制文件的读取和写入。 该参数的设置可以通过my.ini(windows版本)/my.cnf(Linux版本)中设置。 修改完参数
  • Redis数据一致性的介绍

    Redis数据一致性的介绍
    1、一致性 一致性是指系统中各节点数据保持一致。分布式系统中,可以理解为多个节点中的数据是一致的。 一致性根据严苛程度分类: 强
  • Redis数据类型Streams的介绍
    Redis Streams 是 Redis 5.0 引入的一种新的数据类型,它提供了一种强大的日志结构化数据存储方式。Streams 类型非常适合用于构建消息队列、事
  • Redis内存碎片率调优处理方式

    Redis内存碎片率调优处理方式
    1.背景概述 在生产环境中Redis Cluster集群触发了内存碎片化的告警(碎片率1.5),集群节点分布三台宿主机六个节点三主三从架构,Redis版本
  • Redis怎么处理Hash冲突
    在 Redis 中,哈希表是一种常见的数据结构,通常用于存储对象的属性,对于哈希表,最常遇到的是哈希冲突,那么,当 Redis遇到Hash冲突会如
  • Redis实现分布式锁时需要考虑的问题解决方案
    分布式系统中的多个节点经常需要对共享资源进行并发访问,若没有有效的协调机制,可能会导致数据竞争、资源冲突等问题。分布式锁应
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计