当前位置: 首页 > news >正文

Java实现Redis延时队列

“如何实现Redis延时队列”这个面试题应该也是比较常见的,解答如下:
使用sortedset(有序集合) ,拿时间戳作为 score ,消息内容作为key 调用 zadd 来生产消息,消费者用zrangebyscore 指令获取 N 秒之前的数据轮询进行处理。

目录

  • 实现思路
  • 引入Jedis
  • 指令简介
    • zadd
    • zrem
    • zrangeByScore
  • Java实现Redis延时队列

实现思路

Java实现Redis延时队列,首先要了解何为延时队列,即可以将消息存储在队列中,并在指定的延时时间后再将消息出队。这种队列在很多场景下都非常有用,例如消息延时处理,延时确认(订单确认) 等,参考以上解答,思路应该拆分:
首先需要有个延时队列,该队列是通过一定顺序(当前时间戳+延时时间)排序的(即优先取到延时时间已结束的数据),然后消费者端就需要获取到队列中延时时间靠前结束的数据(即当前时间戳+延时时间靠前)。

引入Jedis

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version>
</dependency>

指令简介

zadd

zadd命令用于将一个成员Score值加入到有序集合中。Score值可以是整数或者浮点数。如果有序集合中已经存在相同的成员,那么旧成员将被替代。
语法:ZADD key Score member [Score2 member2 …]
示例:ZADD students 100 alice 或 ZADD students 80 alice 90 bob (添加单个或多个情况)

zrem

zrem命令用于从有序集合中移除一个或多个成员。该命令接收两个参数:第一个参数是要操作的有序集合的键,第二个参数是将要移除的成员的值。
语法:ZREM key member [member …]
示例:ZREM students alice

zrangeByScore

zrangeByScore命令用于获取分数在指定范围内的所有成员。
语法:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
参数说明:
key:Redis中的键。
min:最小分数。
max:最大分数。
WITHSCORES:可选参数,如果设置为true,则返回分数以及成员。
LIMIT:可选参数,用于限制返回的成员数量。
offset:偏移量,从第几个成员开始。
count:限制返回的成员数量。
返回值:
按照分数升序返回成员列表。
如果设置了LIMIT参数,则返回限制数量的成员。
示例:ZADD ZRANGEBYSCORE students 80 90 WITHSCORES

Java实现Redis延时队列

核心部分,消息队列工具类

import redis.clients.jedis.Jedis;
import java.util.Set;public class DelayQueueWithRedis {private Jedis jedis;private String queueKey;public DelayQueueWithRedis(Jedis jedis, String queueKey) {this.jedis = jedis;this.queueKey = queueKey;}// 添加消息到延迟队列public void push(String message, long delaySeconds) {// 计算消息的分数,这里使用消息进入队列的时间加上延迟时间long score = System.currentTimeMillis() / 1000 + delaySeconds;//向有序集合添加一个成员,并设置其分数jedis.zadd(queueKey, score, message);}// 获取并消费一条消息public String pop() {while (true) {long now = System.currentTimeMillis() / 1000;// 只获取分数在0到当前时间的元素Set<String> messages = jedis.zrangeByScore(queueKey, 0, now, 0, 1);if (messages.isEmpty()) {System.out.println("No messages");// 没有可消费的消息,休眠一会儿继续尝试try {Thread.sleep(500);} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}} else {String message = messages.iterator().next();// 从有序集合中移除一个成员jedis.zrem(queueKey, message);return message;}}return null;}
}

生产者端测试

import redis.clients.jedis.Jedis;/*** @Author: zhangximing* @Email: 530659058@qq.com* @Date: 2024/2/19 16:53* @Description: 生产者端测试*/
public class MainP {public static void main(String[] args) {Jedis jedis = new Jedis("localhost",6379);DelayQueueWithRedis delayQueue = new DelayQueueWithRedis(jedis, "delay_queue");// 添加延时消息delayQueue.push("message1", 5);delayQueue.push("message2", 10);delayQueue.push("message3", 8);}}

消费者端测试

import redis.clients.jedis.Jedis;/*** @Author: zhangximing* @Email: 530659058@qq.com* @Date: 2024/2/19 16:51* @Description: 消费者端测试*/
public class MainC {public static void main(String[] args) {Jedis jedis = new Jedis("localhost",6379);DelayQueueWithRedis delayQueue = new DelayQueueWithRedis(jedis, "delay_queue");// 消费延时消息while (true) {String message = delayQueue.pop();if (message != null) {System.out.println("Consumed: " + message);}}}
}

测试结果:数据在延时指定时间后才正常打印
在这里插入图片描述

http://www.lryc.cn/news/302465.html

相关文章:

  • Selenium折线图自动化测试
  • <网络安全>《41 网络攻防专业课<第七课 - IIS上传和Tomcat弱口令漏洞攻击与防范>》
  • 云计算基础-虚拟化概述
  • ElementUI +++ Echarts面试题答案汇总
  • notepad++打开文本文件乱码的解决办法
  • 道可云元宇宙每日资讯|上海开放大学发布“智慧学习中心元宇宙”
  • 压缩感知(Compressed Sensing,CS)的基础知识
  • 如何系统地学习Python
  • SMT2020:半导体制造流程标准仿真测试数据介绍
  • 沁恒CH32V30X学习笔记11---使用外部时钟模式2采集脉冲计数
  • ffmpeg for android编译全过程与遇到的问题
  • 【无标题】力扣报错:member access within null pointer of type ‘struct ListNode‘
  • Qt之Qchar类的接口1
  • vue的十大面试题详情
  • (十四)devops持续集成开发——jenkins流水线使用pipeline方式发布项目
  • 多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型
  • Android 基础技术——Binder 机制
  • 【STM32 CubeMX】STM32中断体系结构
  • JAVA高并发——JDK的并发容器
  • 代码随想录算法训练营day17||二叉树part04、110.平衡二叉树 、257. 二叉树的所有路径 、404.左叶子之和
  • three.js 3D可视化地图
  • Unity所有关于旋转的方法详解
  • Vue3
  • 浅谈业务场景中缓存的使用
  • Itext生成pdf文件,html转pdf时中文一直显示不出来
  • 题目 1138: C语言训练-求矩阵的两对角线上的元素之和
  • 第6讲自定义icon实现
  • 花费200元,我用全志H616和雪糕棒手搓了一台可UI交互的视觉循迹小车
  • AUTOSAR OS TASK
  • 陇剑杯 2021刷题记录