Java实现Redis延时队列

news2024/11/23 17:08:20

“如何实现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.coloradmin.cn/o/1457774.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js_三种方法实现深拷贝

深拷贝&#xff08; 递归 &#xff09; 适用于需要完全独立于原始对象的场景&#xff0c;特别是当对象内部有引用类型时&#xff0c;为了避免修改拷贝后的对象影响到原始对象&#xff0c;就需要使用深拷贝。 // 原始对象 const obj { uname: Lily,age: 19,hobby: [乒乓球, 篮球…

AI论文速读 |【综述】深度学习在多元时间序列插补的应用

论文标题&#xff1a; Deep Learning for Multivariate Time Series Imputation: A Survey 链接&#xff1a;https://arxiv.org/abs/2402.04059 作者&#xff1a;Jun Wang ; Wenjie Du ; Wei Cao ; Keli Zhang ; Wenjia Wang ; Yuxuan Liang ; Qingsong Wen 机构&#xff1a…

『论文阅读|研究用于视障人士户外障碍物检测的 YOLO 模型』

研究用于视障人士户外障碍物检测的 YOLO 模型 摘要1 引言2 相关工作2.1 障碍物检测的相关工作2.2 物体检测和其他基于CNN的模型 3 问题的提出4 方法4.1 YOLO4.2 YOLOv54.3 YOLOv64.4 YOLOv74.5 YOLOv84.6 YOLO-NAS 5 实验和结果5.1 数据集和预处理5.2 训练和实现细节5.3 性能指…

unity 使用VS Code 开发,VS Code配置注意事项

vscode 对应的插件&#xff08;unity开发&#xff09; 插件&#xff1a;.Net Install Tool,c#,c# Dev Kit,IntelliCode For C# Dev Kit,Unity,Unity Code Snippets 本人现在是用了这些插件 unity需要安装Visual Studio Editor 1、.Net Install Tool 设置 需要在设置里面配置…

Idea启动Gradle报错: Please, re-import the Gradle project and try again

Idea启动Gradle报错&#xff1a;Warning:Unable to make the module: reading, related gradle configuration was not found. Please, re-import the Gradle project and try again. 解决办法&#xff1a; 开启步骤&#xff1a;View -> Tool Windows -> Gradle 点击refe…

NX/UG二次开发—CAM—平面铣边界准确设置方法

大家在对平面铣设置边界时&#xff0c;经常遇到边界方向与自己期望的不一致&#xff0c;有些人喜欢用检查刀路是否过切来判断&#xff0c;但是对于倒角、负余量等一些情况&#xff0c;刀路本来就是过切的。对于多边界&#xff0c;可以根据选择的曲线来起点和面的方向来确定&…

多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型

多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型 目录 多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基…

UI美化stylesheet

一、网上找到自己喜欢的图标 大家可以每个图标类型找出三种不同的颜色&#xff0c;方便后续美化效果&#xff0c;这里我每种只找了一个。&#xff08;随便找的&#xff0c;最后效果不好看&#xff09; 将这个文件夹复制到项目的文件夹中。 然后右键Add New…选择QT&#xff0c…

【python】网络爬虫与信息提取--scrapy爬虫框架介绍

一、scrapy爬虫框架介绍 scrapy是一个功能强大的网络爬虫框架&#xff0c;是python非常优秀的第三方库&#xff0c;也是基于python实现网络爬虫的重要技术路线。scrapy不是哟个函数功能库&#xff0c;而是一个爬虫框架。 爬虫框架&#xff1a;是实现爬虫功能的一个软件结构和功…

Spring Boot应用集成Actuator端点解决未授权访问的漏洞

一、前言 我们知道想要实时监控我们的应用程序的运行状态&#xff0c;比如实时显示一些指标数据&#xff0c;观察每时每刻访问的流量&#xff0c;或者是我们数据库的访问状态等等&#xff0c;需要使用到Actuator组件&#xff0c;但是Actuator有一个访问未授权问题&#xff0c;…

C# CAD交互界面-自定义面板集-comboBox选择图层

运行环境Visual Studio 2022 c# cad2016 一、代码说明 SelectLayer方法是一个自定义的AutoCAD命令方法&#xff0c;通过[CommandMethod("SelectLayer")]进行标记。方法首先获取当前活动文档&#xff0c;并检查是否有效。创建一个名为"SelectLayer"的Pale…

云原生概念

云原生是一条使用户能&#xff1a; 1.低运维、 2.敏捷的、 3.以可扩展、可复制的方式&#xff0c; 最大化的利用”云“的能力、发挥”云“的价值的最 佳路径 云原生&#xff0c;是一条最佳路径或实践 参考&#xff1a;https://edu.aliyun.com/course/314164/lesson/7815

docker环境常用容器安装

目录 1.安装partainer 2.安装myql 3.安装redis 4.安装Minio 5.安装zibkin 6.安装nacos 7.安装RabbitMq 8.安装RocketMq 8.1启动service 8.2修改对应配置 8.3启动broker 8.4启动控制台 9.安装sentinel 10.安装elasticsearch 11.安装Kibana 12.安装logstash/file…

Flutter使用问题整理

前言 写这篇文章是为了记录平时在使用flutter时遇到的问题&#xff0c;及解决方案&#xff0c;方便再次遇到时能够快速解决。 问题及解决 问题1 真机运行项目&#xff0c;在构建时提示 Running Gradle task assembleDebug... 41.8s [!] App r…

ECMAScript 2024(ES15)将带来超实用的新特性

ECMAScript语言规范每年都会进行一次更新&#xff0c;而备受期待的 ECMAScript 2024 将于 2024 年 6 月正式亮相。目前&#xff0c;ECMAScript 2024 的候选版本已经发布&#xff0c;为我们带来了一系列实用的新功能。接下来&#xff0c;就让我们一起先睹为快吧&#xff01; 全…

科技云报道:云原生是大模型“降本增效”的解药吗?

科技云报道原创。 在过去一两年里&#xff0c;以GPT和Diffusion model为代表的大语言模型和生成式AI&#xff0c;将人们对AI的期待推向了一个新高峰&#xff0c;并吸引了千行百业尝试在业务中利用大模型。 国内各家大厂在大模型领域展开了激烈的军备竞赛&#xff0c;如&#…

iconfont的使用(最详解)

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

用pandas做简单策略回测

一&#xff0c;RSI策略 数据&#xff1a; 代码 import pandas as pd# 读取贵州茅台股票历史交易数据 df pd.read_csv(贵州茅台股票历史交易数据.csv) missing_values df.isnull().sum()# print("缺失值数量&#xff1a;") # print(missing_values)# 计算RSI指标 …

【LeetCode: 590. N 叉树的后序遍历 + DFS】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

机器学习中梯度下降法的缺点

机器学习中的梯度下降法是一种寻找函数最小值的优化算法&#xff0c;广泛应用于训练各种模型&#xff0c;尤其是在深度学习中。尽管其应用广泛&#xff0c;但梯度下降法也存在一些不可忽视的缺点&#xff1a; 1. 局部最小值和鞍点 局部最小值问题&#xff1a; 对于非凸函数&a…