使用Redis实现延时队列

redis的zset实现延迟队列

延迟队列是什么?

延时队列相比于普通队列最大的区别就体现在其延时的属性上,普通队列的元素是先进先出,按入队顺序进行处理,而延时队列中的元素在入队时会指定一个延迟时间,表示其希望能够在经过该指定时间后处理。从某种意义上来讲,延迟队列的结构并不像一个队列,而更像是一种以时间为权重的有序堆结构。

实现思路:

要实现延时队列Q,可以使用redis zSet的一些命令,比如生产者生成消息,就加入队列里,先简单用定时任务,通过当前的时间戳获取所有的消息,到期的消息自动消费.
发送消息,添加到队列里

key为队列的名称,score为当前的时间戳加上延迟时间,value为消息体

zadd key score value

根据当前时间戳获取所有的消息数据

key为队列的名称,min为0,max为当前的时间戳

zrangebyscore key min max


1,生产者实现

可以看到生产者很简单,其实就是利用zset的特性,给一个zset添加元素而已,而时间就是它的score。

java 复制代码
public void produce(Integer taskId, long exeTime) {
  System.out.println("加入任务, taskId: " + taskId + ", exeTime: " + exeTime + ", 当前时间:" + LocalDateTime.now());
  RedisOps.getJedis().zadd(RedisOps.key, exeTime, String.valueOf(taskId));
}

2,消费者实现

消费者的代码也不难,就是把已经过期的zset中的元素给删除掉,然后处理数据。

java 复制代码
public void consumer() {
  Executors.newSingleThreadExecutor().submit(new Runnable() {
    @Override
    public void run() {
      while (true) {
        Set<String> taskIdSet = RedisOps.getJedis().zrangeByScore(RedisOps.key, 0, System.currentTimeMillis(), 0, 1);
        if (taskIdSet == null || taskIdSet.isEmpty()) {
          System.out.println("没有任务");
  
        } else {
          taskIdSet.forEach(id -> {
            long result = RedisOps.getJedis().zrem(RedisOps.key, id);
            if (result == 1L) {
              System.out.println("从延时队列中获取到任务,taskId:" + id + " , 当前时间:" + LocalDateTime.now());
            }
          });
        }
        try {
          TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  });
}
相关推荐
CryptoPP39 分钟前
韩国股市数据源对接实战:从KOSPI到KOSDAQ的实时行情接入方案
数据库·redis·缓存·金融·区块链
敲个大西瓜11 小时前
Redis一百道核心面试题
数据库·redis·缓存
晚安code17 小时前
RocketMQ 顺序消费实战:批量接口加 Redis Pipeline同步数据
redis·rocketmq
福大大架构师每日一题20 小时前
redis 8.8.1安全更新:一类精心构造的 RESTORE 载荷可触发越界写入,RDB 加载链路全面加固
数据库·redis·缓存
llwszx1 天前
Redis ZSet 完全指南:从应用场景到核心原理
数据库·redis·缓存·跳表·哈希表·zset
難釋懷1 天前
Nginx外置缓存-nginx + redis
redis·nginx·缓存
Valora2 天前
简单学会redis
redis
踏着七彩祥云的小丑2 天前
忘记Redis是否安装过时查看
数据库·redis·缓存
一嘴一个橘子2 天前
redis 通用命令详解
redis
☆凡尘清心☆2 天前
CentOS Stream 9 Redis 7.2.7 源码编译一键安装脚本
linux·运维·redis·centos