基于redis实现延时队列(一)

2023-11-06

背景

最近项目中需要对一条数据,在半小时候更改其状态,类似于提交商城订单半小时后未支付的订单需要更改为超时状态,当然这个解决方案有很多,最好的解决方案是用MQ的死信队列;但由于项目中没有引入MQ,故本文采用的是基于redis与定时器实现该需求。
不废话直接撸串!

代码示例

定义队列名称

public class QueueConstant {
    public static final String DELAY_QUEUE = "delay-queue";
}

将数据放入redis的zset有序集合中

@Autowired
RedisTemplate redisTemplate;

@Value("${timeout:1800000}") //30*60*1000
private Integer timeout;

@Override
public R method(Long id) {
     //业务代码
     ...
     
	 //将订单id(唯一识别号)放入redis中
     redisTemplate.opsForZSet().add(QueueConstant.DELAY_QUEUE,id,System.currentTimeMillis()+timeout);
     return R.success();
 }

定时获取更新状态

@Slf4j
@Configuration
@EnableScheduling
@SuppressWarnings("all")
public class ScheduleTask implements SchedulingConfigurer {
	
	//查询定时表达式
	@Autowired
    CronMapper cronMapper;

    @Autowired
    RedisTemplate redisTemplate;

	//处理业务更新订单状态
    @Autowired
    XXXMapper xxxMapper;

	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

        taskRegistrar.addTriggerTask(() -> {
            log.info("执行超时定时任务: " + LocalDateTime.now().toLocalTime());
            Set<Long> idSet= redisTemplate.opsForZSet().rangeByScore(QueueConstant.DELAY_QUEUE, 0, System.currentTimeMillis());
            if(!CollectionUtils.isEmpty(idSet)){
                for (Long id : idSet) {
                    redisTemplate.opsForZSet().remove(QueueConstant.DELAY_QUEUE,id);
                }
                int num = xxxMapper.closeTimeoutOrder(idSet);
            }
            log.info("执行超时定时任务: 执行条数——>"+idSet.size());
        }, triggerContext -> {
            String cron = cronMapper.getTimeoutCron();
            if (StringUtils.isEmpty(cron)) {
                cron ="30 * * * * ?"; //每隔30秒执行
            }
            return new CronTrigger(cron).nextExecutionTime(triggerContext);
        });
    }
}

从上述中代码中可以看出 定时器我写的是每隔30秒执行一次,虽然频率高但是实时性好,只有当有数据需要处理时才会对数据库产生交互,平时我们项目中救援任务相对较少,所以对数据库基本造不成压力!缺点是没有ACK机制与重试机制。

总结

Redis中Zset 有序集合 实现延时队列,zset是一种特殊的集合,内部成员都是有序排列的,从上述demo中可以看出每个元素都关联一个分数值,跟进这个分数值对元素进行排序。我们把元素的过期时间作为分数值,从而可以实现延时队列。
在这里插入图片描述

  • 将任务最终到期时间作为分值,任务唯一标识作为消息体,添加到队列中
  • 使用rangeByScore,根据当前时间戳获取分值小于当前时间的成员(需要处理的对象)
  • 删除remove过期成员,防止重复消费
  • 对获取到的成员(唯一标识)进行业务处理
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于redis实现延时队列(一) 的相关文章

  • 如何清理redis中不活跃的玩家?

    我正在制作一个使用 redis 来存储游戏状态的游戏 它可以很好地跟踪位置和玩家 但我没有一个好的方法来清理不活跃的玩家 每当玩家移动时 这是一个半慢速移动游戏 想想每秒 1 5 帧 我就会用新位置更新哈希并删除旧位置键 跟踪活跃玩家的最佳
  • 使用 EVAL、SCAN 和 DEL 的 Redis 通配符删除脚本返回“非确定性命令后不允许写入命令”

    因此 我正在寻求构建一个 lua 脚本 该脚本使用 SCAN 根据模式查找键并删除它们 原子地 我首先准备了以下脚本 local keys local done false local cursor 0 repeat local resul
  • Laravel - 缓存 Eloquent 并频繁更新

    是否可以对经常修改的对象使用缓存 例如 假设我们有一个 BlogPost 对象 并且有一个经常更改的 num of views 列 以及其他列 是否可以更新缓存和数据库中的 num of views 字段 而不破坏缓存对象并重新创建它 我可
  • Node.js 上通过套接字连接 Redis

    由于共享托管 目标主机上的我的 redis 服务器不在端口上运行 而是在非常特定的套接字上运行 可以通过套接字文件连接到该套接字 只有我的用户可以访问 但是 我还没有找到如何通过套接字指定连接node redis and connect r
  • Stackexchange.redis 缺乏“WAIT”支持

    我在客户端应用程序正在使用的负载均衡器后面有 3 个 Web API 服务器 我正在使用这个库来访问具有一个主服务器和几个从服务器的 Redis 集群 目前不支持 WAIT 操作 我需要此功能来存储新创建的用户会话并等待它复制到所有从属服务
  • Redis SYNC 套接字上的错误情况:连接被拒绝

    在我的 django 应用程序中使用 celery 和 redis 一切都工作正常 直到我遇到了问题 redis 文件的位置已更改 redis 无法访问它们 经过查找 原来这是由于网络随机攻击造成的 需要添加confg 我添加文件后 一段时
  • 使用 Redis 命令 incr 和 expire 时的竞争条件

    根据redis文档 http redis io commands incr http redis io commands incr 在段落模式 速率限制器 2 较短的版本代码 value INCR ip IF value 1 THEN EX
  • 如何在Redis中进行持久化存储?

    关闭redis服务器后 使用set存储的值被破坏 在这里我找到了使用持久性存储的方法 有人帮助我 如何使用javascript实现这一点 我想将客户端的一些值存储在 redis 数据库中 并且必须在其他客户端中使用该值 您需要配置 Redi
  • Lua中按字符分割字符串

    我有像这样的字符串 ABC DEF 我需要将它们分开 字符并将两个部分分别分配给一个变量 在 Ruby 中 我会这样做 a b ABC DEF split 显然Lua没有这么简单的方法 经过一番挖掘后 我找不到一种简短的方法来实现我所追求的
  • Java 将字节转换为二进制安全字符串

    我有一些以字节为单位的数据 我想将它们放入Redis中 但是Redis只接受二进制安全字符串 而我的数据有一些二进制非安全字节 那么如何将这些字节转换为二进制安全字符串以便将它们保存到 Redis 中呢 Base64 对我有用 但它使数据更
  • Redis、会话过期和反向查找

    我目前正在构建一个网络应用程序 并想使用 Redis 来存储会话 登录时 会话会使用相应的用户 ID 插入到 Redis 中 并且过期时间设置为 15 分钟 我现在想实现会话的反向查找 获取具有特定用户 ID 的会话 这里的问题是 由于我无
  • Spring Data JPA Redis:无法编写基于自定义方法的查询

    我已经使用 Redis 配置了 Spring Data JPA 并使用RedisRepositorieswith 提供了类似的方法find findAll 所有这些方法似乎都工作得很好 但我无法编写我的自定义方法 RedisEntity f
  • Laravel 所有会话 ID 与 Redis 驱动程序

    在我的应用程序中 我希望允许某些用户能够注销除他 她之外的所有其他用户 当会话驱动程序设置为文件时 我已经完成了此功能 但现在我使用 redis 作为会话驱动程序 并且我无法找到任何方法来列出所有当前会话 就像我在文件时所做的那样司机 问题
  • redis - 使用哈希

    我正在使用 redis 为我的 Web 应用程序实现社交流和通知系统 我是 redis 的新手 我对哈希值及其效率有一些疑问 我读过这篇很棒的文章Instagram 帖子 http instagram engineering tumblr
  • StackExchange.Redis的正确使用方法

    这个想法是使用更少的连接和更好的性能 连接会随时过期吗 对于另一个问题 redis GetDatabase 打开新连接 private static ConnectionMultiplexer redis private static ID
  • 使用redis进行树形数据结构

    我需要为基于树的键值开发一个缓存系统 与Windows注册表编辑器非常相似 其中缓存键是字符串 表示树中到值的路径 可以是原始类型 int string bool double 等 或子树本身 例如 key root x y z w val
  • Spring Redis删除不删除key

    我正在尝试删除一个 Redis 键 但由于某种原因它没有删除 但也没有抛出异常 这是我要删除的代码 import com example service CustomerService import com example model Cu
  • Laravel 异常队列最大尝试次数超出

    我创建了一个应用程序来向多个用户发送电子邮件 但在处理大量收件人时遇到问题 该错误出现在failed jobs table Illuminate Queue MaxAttemptsExceededException App Jobs ESe
  • 创建 C++ Redis 模块 - “不导出 RedisModule_OnLoad() 符号”

    我在加载 Redis 模块时遇到一些问题 我只是复制来自的示例https redis io topics modules intro https redis io topics modules intro 但我把它剥下来了 include
  • 节点应用程序之间共享会话?

    我目前有两个独立的节点应用程序在两个不同的端口上运行 但共享相同的后端数据存储 我需要在两个应用程序之间共享用户会话 以便当用户通过一个应用程序登录时 他们的会话可用 并且他们似乎已登录到另一个应用程序 在本例中 它是一个面向公众的网站和一

随机推荐

  • python anova_使用Python进行双向ANOVA的三种方法

    python anova In an earlier post I showed four different techniques that enables two way analysis of variance ANOVA using
  • VS2010调试-显示堆栈窗口

    以中断模式或运行模式显示 调用堆栈 窗口 在 调试 菜单中选择 窗口 然后单击 调用堆栈 或者 ALT 7 更改显示的可选信息 右击 调用堆栈 窗口 然后设置或清除 显示 lt 所需信息 gt 在 调用堆栈 窗口中显示非用户代码帧 右击 调
  • javascript Date format(js日期格式化)

    javascript Date format js日期格式化 方法一 对Date的扩展 将 Date 转化为指定格式的String 月 M 日 d 小时 h 分 m 秒 s 季度 q 可以用 1 2 个占位符 年 y 可以用 1 4 个占位
  • SAP 资产屏幕增强(AS01/AS02/AS03)

    导语 最新需要在资产屏幕上增加增强字段 效果图在最后 下面分享一下实现过程 一 在表中增强字段 本次增强的是 资产主数据 gt 源 中的字段 选择储存在ANLU表中 二 创建屏幕 在函数组XAIS中创建屏幕9001 在屏幕上绘制需要增强的字
  • webpack性能优化

    webpack性能优化 性能优化介绍 开发环境性能优化 生产环境性能优化 开发环境性能优化 HMR hot module replacement 开发环境下调试代码 source map oneOf 缓存 tree shaking 去除无用
  • 计算m个A,n个B可以组合成多少个不同排列的问题。---C语言

    计算m个A n个B可以组合成多少个不同排列的问题 例如计算3个A 2个B可以组成多少种排列 如 AAABB AABBA 根据题目 我们要计算出其排列组合的个数 需要先把组合中的各个字母拿出来 并且计算有多少个 然后根据个数 计算其排列组合的
  • 关于jqGrid的multiselect,multiboxonly,multikey

    今天又解决了个大难题 不知道用jqGrid的朋友遇到过没有 当我们设置multiselect为true时 选择任何的单元格 都会选中该行 万一设置了单元格编辑功能 岂不是每次都要取消选中的行 由于查看国内的网站 发现仅仅都是介绍了jqGri
  • ChatGPT的 6 个强势升级:重点是超强的文件上传和分析功能也来啦!

    发布会核心概览 前日凌晨 OpenAI在社交平台上宣布了一系列新功能 旨在提升用户体验 这6 个新功能包括 提示示例 回答建议 GPT 4默认选择 可分析上传多个文件 保持登录状态和键盘快捷键 其中 可分析上传多个文件的功能非常强大 结合最
  • Leecode392.判断子序列

    题目描述 给定字符串 s 和 t 判断 s 是否为 t 的子序列 字符串的一个子序列是原始字符串删除一些 也可以不删除 字符而不改变剩余字符相对位置形成的新字符串 例如 ace 是 abcde 的一个子序列 而 aec 不是 进阶 如果有大
  • MicroPython——将固件烧写到STM32开发板上

    博主是在 win10环境下 将MicroPython固件烧录到stm32F407开发板上 因为博主想学一波STM32F407 有python基础 但c语言基础一般 觉得学库函数觉得太过复杂 且以后方向可能不太搞嵌入式硬件 所以就用Mirco
  • Eclipse 快捷健

    查询 F3 全局 打开声明 Ctrl G 工作区中的声明 Ctrl shift G 查看变量或方法在工作区的引用 Ctrl Alt H Call Hierarchy 查找出该工程所有调用了该成员变量或方法 Ctrl H 打开搜索对话框 Ct
  • PyQt5 界面预览工具

    简介 一款为了预览PyQt5设计的UI界面而开发的工具 使用时需要结合PyCharm同时使用 下载 PyQt5界面预览工具 参数说明 使用配置 启动PyCharm 找到File gt Settings 打开 找到Tools gt Exter
  • [Java基础]Java中boolean类型到底占用多少个字节?

    1 时间 2017 07 03 07 37 06 YuanMxy 2 问题描述 今天在复习java基础的时候发现一小问题 Java中boolean类型到底占用多少个字节 3 问题解答 1 什么是boolean类型 根据官方文档的描述 htt
  • 在aps.net开发时,改变页面对应的js代码后,重新加载页面后js代码没有加载为最新版本?

    例如页面引用js文件的代码为 在开发人员修改完js代码后 发现重新加载页面时新的js代码不会生效 这是因为页面在向js发出请求时 浏览器发现js文件名和参数没有变化 所以默认 加载了缓存中存在的js代码 可以这样解决这个问题 将页面引用js
  • idea重写接口没有@override_乐字节Java继承|方法重写、super和final关键字

    大家好 乐字节的小乐又来了 上一篇是 乐字节Java JavaBean 继承与权限修饰 也是属于Java继承的 今天继续Java继承 一 方法的重写 父类不满足子类的要求 按需改写 注意 方法签名必须相同 在子类中可以根据需要对从基类中继承
  • 如何进行云主机迁移?看这一篇文章就够了!

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由腾讯云计算产品团队发表于云 社区专栏 主机迁移概述 在云计算时代 不管是从IDC上云还是多云直接的迁移 都已经是常见的事宜 而在上云 迁移的方案中 也是有多种的方式能够将主机迁
  • 【颜纠日记】win10开启高性能超频模式,你不知道的N种方法。

    颜纠日记 1 启用游戏模式 Win10 中调整游戏性能最简单的方法 就是启用游戏模式 开启游戏模式 可以通过停止 Windows 更新和一些应用程序的后台活动 来提高游戏帧数 如果不确定是否开启了游戏模式 可以转到 Win I 游戏 游戏模
  • 3D游戏(2)——离散仿真引擎基础

    文章目录 1 简答题 解释 游戏对象 GameObjects 和 资源 Assets 的区别与联系 下载几个游戏案例 分别总结资源 对象组织的结构 指资源的目录组织结构与游戏对象树的层次结构 编写一个代码 使用 debug 语句来验证 Mo
  • Android:WebView加载url网页显示不完整解决办法

    WebView基本用法 如果想要在APP里面加载url网页 或者html代码 首先我们会想到WebView 它的基本用法如下 webview layout xml
  • 基于redis实现延时队列(一)

    背景 最近项目中需要对一条数据 在半小时候更改其状态 类似于提交商城订单半小时后未支付的订单需要更改为超时状态 当然这个解决方案有很多 最好的解决方案是用MQ的死信队列 但由于项目中没有引入MQ 故本文采用的是基于redis与定时器实现该需