Redis延时队列方案

11 篇文章 0 订阅

总体方案
创建一个定时任务,每一次执行完后间隔一定时间就会扫描缓存,缓存中一旦添加了任务,就会被扫描到,然后发送到消息队列,监听器一旦监听到消息就会进行处理,如果处理失败,则再次生成任务(次数加1,时间戳会根据规则增加),到达规定次数后则不在执行

具体细节
首先创建一个执行完后间隔’ w e b h o o k . f i x e d D e l a y ’ 后 执 行 下 一 次 , 从 缓 存 中 取 出 数 据 , 一 旦 取 到 数 据 就 发 送 到 消 息 队 列 中 , 并 且 删 除 掉 缓 存 里 面 的 数 据 ! [ 在 这 里 插 入 图 片 描 述 ] ( h t t p s : / / i m g − b l o g . c s d n i m g . c n / 2019041020062966. p n g ? x − o s s − p r o c e s s = i m a g e / w a t e r m a r k , t y p e Z m F u Z 3 p o Z W 5 n a G V p d G k , s h a d o w 1 0 , t e x t a H R 0 c H M 6 L y 9 i b G 9 n L m N z Z G 4 u b m V 0 L 3 d l a X h p b l 80 N D M y M T k 0 M g = = , s i z e 1 6 , c o l o r F F F F F F , t 7 0 ) 监 听 器 一 旦 监 听 到 消 息 就 会 进 行 处 理 , 如 果 处 理 失 败 , 则 再 次 生 成 任 务 ( 次 数 加 1 , 时 间 戳 会 根 据 规 则 增 加 ) , 到 达 规 定 次 数 后 则 不 在 执 行 @ R a b b i t L i s t e n e r ( q u e u e s = " {webhook.fixedDelay}’后执行下一次,从缓存中取出数据,一旦取到数据就发送到消息队列中,并且删除掉缓存里面的数据 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2019041020062966.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMyMTk0Mg==,size_16,color_FFFFFF,t_70) 监听器一旦监听到消息就会进行处理,如果处理失败,则再次生成任务(次数加1,时间戳会根据规则增加),到达规定次数后则不在执行 @RabbitListener(queues = " webhook.fixedDelay,,,![](https://imgblog.csdnimg.cn/2019041020062966.png?xossprocess=image/watermark,typeZmFuZ3poZW5naGVpdGk,shadow10,textaHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMyMTk0Mg==,size16,colorFFFFFF,t70)1@RabbitListener(queues="{webhook.queue}")
// 参数中使用@Header获取mesage
public void helloReply(String json) {
logger.debug(“task:{}”, json);
Task task = gson.fromJson(json, Task.class);
try {
handler.handler(task.getData());
} catch (Exception e) {
if (webhookUtil.getInterval().size() > task.getTimes()) {
Task next = new Task();
next.setTimes(task.getTimes() + 1);
next.setTimestamp(task.getTimestamp() + webhookUtil.getInterval().get(task.getTimes())*1000);
next.setData(task.getData());
webhookUtil.addNext(next);
if (logger.isDebugEnabled()) {
logger.debug(“处理失败,添加到下次执行:” + gson.toJson(task), e);
}
} else {
logger.error(“处理{}次失败,停止处理”, webhookUtil.getInterval().size(), e);
}
}

}

测试
向缓存中添加一条数据,定时任务会到时间自动检测到这条数据
在这里插入图片描述
配置文件
spring-mq.xml
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Redis延时队列是通过使用Redis的有序集合(zset)来实现的。有序集合的特点是可以对元素进行排序,而延时队列中的消息可以根据延迟时间进行排序。每个消息在有序集合中都有一个对应的score,表示消息的到期时间。当消息的到期时间到达时,可以通过监听Redis的失效事件来触发相应的处理逻辑。\[1\] Redis作为内存数据库,具有高性能和快速的读写速度。它还支持持久化机制,可以通过AOF和RDB方式对数据进行恢复,保证数据的可靠性。此外,Redis可以搭建集群来提高消息处理的速度和可用性。\[2\] 在实现延时队列时,可以使用Redis的zset来存储消息,并使用score来表示消息的到期时间。当消息到期时,可以通过监听Redis的失效事件来触发相应的处理逻辑。另外,也可以使用一些组件或者消息队列来实现延时队列,比如Redis的sortset间接实现、Kafka的内部时间轮、RabbitMQ的插件等。不过需要注意的是,Redis本身并不适合大量消息堆积,因此适用于相对简单的场景。如果对消息的实时性和可靠性要求较高,可能需要使用消息队列或者Kafka来实现延时队列。\[3\] 总结来说,Redis延时队列是通过使用Redis的有序集合来实现的,可以利用其高性能和持久化机制。但需要注意Redis的适用场景和限制,以及根据实际需求选择合适的实现方式。 #### 引用[.reference_title] - *1* [redis实现延迟队列](https://blog.csdn.net/weixin_44275820/article/details/120507859)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [redis-延迟队列](https://blog.csdn.net/weixin_42128977/article/details/126152834)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值