Java实现Redis延时队列

这篇具有很好参考价值的文章主要介绍了Java实现Redis延时队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

实现思路

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,java,redis,延时队列文章来源地址https://www.toymoban.com/news/detail-828483.html

到了这里,关于Java实现Redis延时队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RabbitMQ延时队列的详细介绍以及Java代码实现

    前言:大家好,我是小威,24届毕业生,在一家满意的公司实习。本篇文章将详细介绍RabbitMQ的延时队列以及其详细代码实现。 如果文章有什么需要改进的地方还请大佬不吝赐教 👏👏。 小威在此先感谢各位大佬啦~~🤞🤞 🏠个人主页:小威要向诸佬学习呀 🧑个人简介:大

    2024年02月01日
    浏览(29)
  • 【Java】SpringBoot中实现Redis Stream队列

    简单实现一下在SpringBoot中操作Redis Stream队列的方式,监听队列中的消息进行消费。 jdk:1.8 springboot-version:2.6.3 redis:5.0.1(5版本以上才有Stream队列) 1 pom redis 依赖包(version 2.6.3) 2 yml 3 RedisStreamUtil 工具类 生产者发送消息 生产者发送消息,在Service层创建 addMessage 方法,往

    2024年04月11日
    浏览(26)
  • springboot自定义注解+aop+redis实现延时双删

    redis作为用的非常多的缓存数据库,在多线程场景下,可能会出现数据库与redis数据不一致的现象 数据不一致的现象:https://blog.csdn.net/m0_73700925/article/details/133447466 这里采用aop+redis来解决这个方法: 删除缓存 更新数据库 延时一定时间,比如500ms 删除缓存 这里之所以要延时一

    2024年01月17日
    浏览(32)
  • 微服务---Redis实用篇-黑马头条项目-优惠卷秒杀功能(使用java阻塞队列对秒杀进行异步优化)

    1.1 秒杀优化-异步秒杀思路 我们来回顾一下下单流程 当用户发起请求,此时会请求nginx,nginx会访问到tomcat,而tomcat中的程序,会进行串行操作,分成如下几个步骤 1、查询优惠卷 2、判断秒杀库存是否足够 3、查询订单 4、校验是否是一人一单 5、扣减库存 6、创建订单 在这六

    2024年02月05日
    浏览(37)
  • 基于 Redis 实现高性能、低延迟的延时消息的方案演进

    🎉欢迎来系统设计专栏:基于 Redis 实现高性能、低延迟的延时消息的方案演进 📜其他专栏:java面试 数据结构 源码解读 故障分析 🎬作者简介:大家好,我是小徐🥇 ☁️博客首页:CSDN主页 小徐的博客 🌄每日一句: 好学而不勤非真好学者 📜 欢迎大家关注! ❤️ 随着

    2024年01月22日
    浏览(43)
  • kafka延时队列原理,Java开发中遇到最难的问题

    Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么? Dubbo 的整体架构设计有哪些分层? 什么是 Spring Boot?以及Spring Boot的优劣势? 你如何理解 Spring Boot 中的 Starters? 服务注册和发现是什么意思?Spring Cloud 如何实现? Spring Cloud断路器的作用

    2024年03月21日
    浏览(37)
  • JAVA 实现 Redis 发布订阅

    发布订阅: 消息发布者发布消息 和 消息订阅者接收消息 ,两者之间通过某种媒介联系起来 例如订杂志,当自己订阅了爱格杂志,每个月会发刊一本。到发布的时候派送员将杂志送到自己手上就能看到杂志内容。只有我们订阅了该杂志才会派送给我们 Redis 发布订阅(pub/su

    2024年02月14日
    浏览(29)
  • Java使用Redis实现分页功能

    分页功能实现应该是比较常见的,对于redis来说,近期刷题就发现了lrange、zrange这些指令,这个指令怎么使用呢? 我们接下来就来讲解下。 lrange 是 Redis 中的一个命令,用于从 列表中 获取指定范围内的元素。 语法:lrange key start end start 和 end是两个整数,表示要从列表中获取

    2024年02月21日
    浏览(37)
  • java实战:Redis实现查找附近的人

    本文将介绍如何使用Redis实现查找附近的人的功能。我们将探讨如何使用Redis的地理空间(Geospatial)索引功能,并展示一个简单的Java代码示例,该示例使用Jedis库和Redis的GEOADD命令来添加位置信息,以及使用GEORADIUS命令来查找附近的人。通过本文,可以了解到如何在Java应用程

    2024年02月21日
    浏览(27)
  • redis — 基于Spring Boot实现redis延迟队列

    1. 业务场景 延时队列场景在我们日常业务开发中经常遇到,它是一种特殊类型的消息队列,它允许把消息发送到队列中,但不立即投递给消费者,而是在一定时间后再将消息投递给消费者。延迟队列的常见使用场景有以下几种: 在各种购物平台上下单,订单超过30分钟未支付

    2024年02月13日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包