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);}}}
}
测试结果:数据在延时指定时间后才正常打印
相关文章:
Java实现Redis延时队列
“如何实现Redis延时队列”这个面试题应该也是比较常见的,解答如下: 使用sortedset(有序集合) ,拿时间戳作为 score ,消息内容作为key 调用 zadd 来生产消息,消费者用zrangebyscore 指令获取 N …...
Selenium折线图自动化测试
目录 获取折线图echarts实例 获取折线图实例锚点的坐标 通过echarts实例的getOption()方法获取坐标数据 将折线图坐标点转换为像素坐标值 整合折线图坐标数据 根据折线图坐标计算出锚点相对于浏览器中的坐标 计算canvas画布原点的坐标 计算折线图相对于浏览器的坐标 使用…...
<网络安全>《41 网络攻防专业课<第七课 - IIS上传和Tomcat弱口令漏洞攻击与防范>》
1 中间件PUT漏洞介绍 中间件包括apache、tomcat、IIS、weblogic等,这些中间件可以设置支持的HTTP方法。(HTTP方法包括GET、POST、HEAD、DELETE、PUT、OPTIONS等) 每一个HTTP方法都有其对应的功能,在这些方法中,PUT可…...
云计算基础-虚拟化概述
虚拟化概述 虚拟化是一种资源管理技术,能够将计算机的各种实体资源(如CPU、内存、磁盘空间、网络适配器等)予以抽象、转换后呈现出来并可供分割、组合为一个或多个逻辑上的资源。这种技术通过在计算机硬件上创建一个抽象层,将单台…...
ElementUI +++ Echarts面试题答案汇总
官网地址:http://element-cn.eleme.io/#/zh-CN ElementUI是一套基于VUE2.0的桌面端组件库,ElementUI提供了丰富的组件帮助开发人员快速构建功能强大、风格统一的页面。 ElementUi是怎么做表单验证的?在循环里对每个input验证怎么做呢&#x…...
notepad++打开文本文件乱码的解决办法
目录 第一步 在编码菜单栏下选择GB2312中文。如果已经选了忽略这一步 第二步 点击编码,红框圈出来的一个个试。我切换到UTF-8编码就正常了。 乱码如图。下面分享我的解决办法 第一步 在编码菜单栏下选择GB2312中文。如果已经选了忽略这一步 第二步 点击编码&#…...
道可云元宇宙每日资讯|上海开放大学发布“智慧学习中心元宇宙”
道可云元宇宙每日简报(2024年2月19日)讯,今日元宇宙新鲜事有: 上海开放大学发布“智慧学习中心元宇宙” 上海开放大学首次发布了“智慧学习中心元宇宙”,初步构筑了上海开放大学5g元宇宙孪生学习环境,13所…...
压缩感知(Compressed Sensing,CS)的基础知识
压缩感知(Compressed Sensing,CS)是一种用于信号处理的技术,旨在以少于奈奎斯特采样定理所要求的样本频率来重构信号。该技术利用信号的稀疏性,即信号可以用较少的非零系数表示。压缩感知在图像获取中的应用使得在采集…...
如何系统地学习Python
建议系统学习Python的途径遵循理论与实践相结合的教学方法。以下是一个分阶段的学习计划: 阶段一:基础知识 理解Python的特点: 认识Python的历史与设计哲学。学习Python的基本语法和运行环境。 安装Python: 学习如何在不同操作系…...
SMT2020:半导体制造流程标准仿真测试数据介绍
文章目录 问题背景SMT2020 涉及的主要功能1. 包含多种仿真模型类型2. 包含非计划性动作3. 区分不同类型设备的加工速率4. 特殊的复杂操作SMT2020 数据概览1. AutoSched 仿真模型数据2. General Data 输入数据问题背景 在半导体的生产制造当中,由于晶元片及设备等的高价值性,…...
沁恒CH32V30X学习笔记11---使用外部时钟模式2采集脉冲计数
使用外部时钟模式2采集脉冲计数 使用外部触发模式 2 能在外部时钟引脚输入的每一个上升沿或下降沿计数。将 ECE 位置位时,将使用外部时钟源模式 2。使用外部时钟源模式 2 时,ETRF 被选定为 CK_PSC。ETR 引脚经过可选的反相器(ETP),分频器(ETPS)后成为 ETRP,再经过滤波…...
ffmpeg for android编译全过程与遇到的问题
编译前准备 编译环境:Ubuntu16,可自行下载VMWare最新版并百度永久许可证或在服务器上安装Ubuntu ffmpeg源码:ffmpeg4.2.2 NDK下载:Android NDK r21e 有条件的最好还是在Liunx平台下编译吧,Windows平台下编译坑更多…...
【无标题】力扣报错:member access within null pointer of type ‘struct ListNode‘
项目场景: 做单链表反转题目,报错:member access within null pointer of type ‘struct ListNode’ 题目链接:LINK 问题描述 我明明在初始化指针时候,已经处理了n2->next情况却依然报错 这个报错提示含义是:大概就…...
Qt之Qchar类的接口1
Qt类的构造函数 QChar类提供了许多个不同原型的构造函数,以方便不同场合下使用。 QChar(); //构造一个空字符,即‘\0’ QChar(char ch); //由字符数据ch构造 QChar(uchar ch)…...
vue的十大面试题详情
1 v-show与v-if区别 v-if与v-show可以根据条件的结果,来决定是否显示指定内容: v-if: 条件不满足时, 元素不会存在. v-show: 条件不满足时, 元素不会显示(但仍然存在). <div id"app"><button click"show !show">点我</but…...
(十四)devops持续集成开发——jenkins流水线使用pipeline方式发布项目
前言 本节内容我们使用另外一种方式pipeline实现项目的流水线部署发布,Jenkins Pipeline是一种允许以代码方式定义持续集成和持续交付流水线的工具。通过Jenkins Pipeline,可以将整个项目的构建、测试和部署过程以脚本的形式写入Jenkinsfile中ÿ…...
多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型
多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型 目录 多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基…...
Android 基础技术——Binder 机制
笔者希望做一个系列,整理 Android 基础技术,本章是关于Binder 机制 什么是Binder 机制:Binder 是一种进程间通信机制 驱动:Binder 是一个虚拟物理设备驱动 应用层:Binder 是一个能发起通信的 Java 类 为什么要使用Bind…...
【STM32 CubeMX】STM32中断体系结构
文章目录 前言一、中断体系的比喻二、中断的内部结构2.1 EXTI触发方式 2.2 NVIC2.3 cpu与中断2.4 外部中断控制器框图上升沿触发选择寄存器屏蔽/使能寄存器等待处理寄存器 2.5 中断优先级 总结 前言 一、中断体系的比喻 STM32中断体系如下图所示: 一座大型建筑物…...
JAVA高并发——JDK的并发容器
文章目录 1、超好用的工具类:并发集合简介2、线程安全的HashMap3、深入浅出ConcurrentHashMap3.1、ConcurrentHashMap的内部数据结构3.2、put()方法的实现3.3、get()方法的实现 4、有关List的线程安全5、高效读写的队列:深度剖析ConcurrentLinkedQueue类…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
