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.mfbz.cn/a/396460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Vuforia+Unity】01实现单张多张图片识别产生对应数字内容

1.官网注册 Home | Engine Developer Portal 2.下载插件SDK&#xff0c;导入Unity 3.官网创建数据库上传图片&#xff0c;官网处理成数据 下载好导入Unity&#xff01; 下载好导入Unity&#xff01; 下载好导入Unity&#xff01; 下载好导入Unity&#xff01; 4.在Unity设…

iconfont的使用(最详解)

目录 一、Iconfont是什么&#xff1f; 二、Iconfont如何使用 1.官网注册 2.新建项目 3.项目中使用 Unicode方式 Font class方式 Symbol方式 三、总结 一、Iconfont是什么&#xff1f; iconfont是阿里旗下的一套图标库&#xff0c;UI设计师设计号图标后&#xff0c;会…

FL Studio21.2注册激活码免费版安装包下载

FL Studio 21的音乐编辑功能强大而全面&#xff0c;能够满足音乐制作人在音乐创作过程中的各种需求。以下是一些主要特点&#xff1a; FL Studio 21 Win-安装包下载如下: https://wm.makeding.com/iclk/?zoneid55981 FL Studio 21 Mac-安装包下载如下: https://wm.makedin…

Java 基于微信小程序的考研论坛系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

使用SiteScan合理信息收集

一、介绍 作者&#xff1a;kracer 定位&#xff1a;专注一站式解决渗透测试的信息收集任务。 语言&#xff1a;python3开发 功能&#xff1a;包括域名ip历史解析、nmap常见端口爆破、子域名信息收集、旁站信息收集、whois信息收集、网站架构分析、cms解析、备案号信息收集、…

JVM性能调优P69+

方法 线程转储的查看方式 火焰图 线程耗尽问题

压缩感知(Compressed Sensing,CS)的基础知识

压缩感知&#xff08;Compressed Sensing&#xff0c;CS&#xff09;是一种用于信号处理的技术&#xff0c;旨在以少于奈奎斯特采样定理所要求的样本频率来重构信号。该技术利用信号的稀疏性&#xff0c;即信号可以用较少的非零系数表示。压缩感知在图像获取中的应用使得在采集…

《Solidity 简易速速上手小册》第3章:Solidity 语法基础(2024 最新版)

文章目录 3.1 变量和类型3.1.1 基础知识解析详细解析变量类型深入数据类型理解变量可见性 3.1.2 重点案例&#xff1a;创建一个简单的存储合约案例 Demo&#xff1a;编写一个简单的数字存储合约案例代码&#xff1a;SimpleStorage.sol在 Remix 中进行交互&#xff1a;拓展操作&…

css3盒子

盒子模型 一.看透网页布局本质二.认识盒子三.盒子的边框&#xff08;border&#xff09;1.概念2.简写及分开写法3.合并问题&#xff08;会相加&#xff09;4.边框会影响盒子实际大小 四.盒子的内边距&#xff08;padding&#xff09;1.概念2.简写3.内边距会影响盒子实际大小4.特…

小迪安全2023最新版笔记集合--续更

小迪安全2023最新版笔记集合–续更 小迪安全2023最新笔记集合 章节一 ---- 基础入门&#xff1a; 知识点集合&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗透命令&#xff1a;文件上传下…

代码随想录刷题笔记-Day20

1. 二叉树的最近公共祖先 236. 二叉树的最近公共祖先https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/ 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#x…

NS安装-CentOS服务器安装Nightscout CGM

NS CGM 安装必要条件 有自己的云服务器好像没有2&#xff0c;有云服务器就行了 安装顺序 先安装数据库&#xff0c;目前支持的是 MongoDB &#xff0c;官方推荐4&#xff0c;其实目前最新版本就行。可以用宝塔安装&#xff0c;比较简单克隆代码&#xff0c;我是放到 /opt/ns…

自动化上位机开发C#100例:如何用面向对象的方式封装雷赛运动控制卡EtherCAT总线卡(C#代码)

自动化上位机开发C#100例:雷赛运动控制卡EtherCAT总线卡C#封装类 文章目录 LTDMC.dll下载LTDMC.cs LTDMC.dll C#调用封装下载ICard.cs 运动控制卡接口Card.cs 运动控制卡抽象类CardLTDMC.cs 雷赛运动控制卡EtherCAT总线卡实现类CardList.cs 总线卡列表封装 LTDMC.dll下载 最新…

HarmonyOS4.0系列——08、整合UI常用组件

HarmonyOS4.0 系列——08、UI 组件 Blank Blank 组件在横竖屏占满空余空间效果 // xxx.ets Entry Component struct BlankExample {build() {Column() {Row() {Text(Button).fontSize(18)Blank()Toggle({type: ToggleType.Switch}).margin({top: 14,bottom: 14,left: 6,righ…

Cannot invoke “java.sql.Connection.prepareStatement(String)“ because “conn“

下载sqlite-jdbc&#xff0c;放在目录下&#xff0c;然后IDEA右键jar文件选择“加入库”即可解决 Central Repository: org/xerial/sqlite-jdbc/3.36.0.1

第一个 Angular 项目 - 动态页面

第一个 Angular 项目 - 动态页面 使用的所有技巧都在下面的笔记里&#xff1a; [Angular 基础] - 数据绑定(databinding) [Angular 基础] - 指令(directives) 以上为静态页面&#xff0c;即不涉及到跨组件交流的内容 以下涉及到组件内的沟通&#xff0c;从这开始数据就“活”…

板块一 Servlet编程:第四节 HttpServletResponse对象全解与重定向 来自【汤米尼克的JAVAEE全套教程专栏】

板块一 Servlet编程&#xff1a;第四节 HttpServletResponse对象全解与重定向 一、什么是HttpServletResponse二、响应数据的常用方法三、响应乱码问题字符流乱码字节流乱码 四、重定向&#xff1a;sendRedirect请求转发和重定向的区别 在上一节中&#xff0c;我们系统的学习了…

react封装通用Modal弹窗组件

目录 1、【src/component/modal/hoc.js】 2、【src/component/modal/componentModal.js】 3、【src/page/projectView.js】 【说明】&#xff1a;后台管理的项目中会经常遇到弹窗&#xff0c;于是封装了一个简单的公共弹窗组件 这个公共组件不适用复杂的功能&#xff0c;简单的…

业务型 编辑器组件的封装(复制即可使用)

使用需要安装 wangeditor npm i --save wangeditor import React from react; import E from wangeditor; import ./index.lessclass EditorElem extends React.Component {constructor(props) {super(props);this.isChange false;this.state {}}componentDidMount() {con…

并发List、Set、ConcurrentHashMap底层原理

并发List、Set、ConcurrentHashMap底层原理 ArrayList: List特点&#xff1a;元素有放入顺序&#xff0c;元素可重复 存储结构&#xff1a;底层采用数组来实现 public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Clon…
最新文章