灵感来袭,基于Redis的分布式延迟队列
延迟队列
延迟队列,也就是一定时间之后将消息体放入队列,然后消费者才能正常消费。比如1分钟之后发送短信,发送邮件,检测数据状态等。
Redisson Delayed Queue
如果你项目中使用了redisson,那么恭喜你,使用延迟队列将非常的简单。
基于Redis的Redisson分布式延迟队列(Delayed Queue)结构的RDelayedQueue
Java对象在实现了RQueue
接口的基础上提供了向队列按要求延迟添加项目的功能。该功能可以用来实现消息传送延迟按几何增长或几何衰减的发送策略。
RQueue<String> distinationQueue = ...
RDelayedQueue<String> delayedQueue = getDelayedQueue(distinationQueue);
// 10秒钟以后将消息发送到指定队列
delayedQueue.offer("msg1", 10, TimeUnit.SECONDS);
// 一分钟以后将消息发送到指定队列
delayedQueue.offer("msg2", 1, TimeUnit.MINUTES);
在该对象不再需要的情况下,应该主动销毁。仅在相关的Redisson对象也需要关闭的时候可以不用主动销毁。
Java DelayQueue
DelayQueue它本质上是一个队列,而这个队列里也只有存放Delayed的子类才有意义。
延迟队列demo
public class DelayTask implements Delayed {
private long startDate;
public DelayTask(Long delayMillions) {
this.startDate = System.currentTimeMillis() + delayMillions;
} @Override
public int compareTo(Delayed o) {
Long.compare(this.getDelay(TimeUnit.NANOSECONDS), o.getDelay(TimeUnit.NANOSECONDS));
} @Override
public long getDelay(TimeUnit unit) {
return this.startDate - System.currentTimeMillis();
} public static void main(String[] args) throws Exception {
BlockingQueue<DelayTask> queue = new DelayQueue<>();
DelayTask delayTask = new DelayTask(1000 * 5L);
queue.put(delayTask);
while (queue.size()>0){
queue.take();
}
}
}
延迟队列消费原理
- 第一次是当队列为空时,等待;
- 第二次等待是因为,发现有任务,没有到执行时间,并且有准备执行的线程(leader),那不好意思,还得接续等待直到下一个可执行的任务。
- 第三次是真正延时的地方了,available.awaitNanos(delay),此时也没有别的线程要执行,也就是我将要执行,等待剩下的延迟时间即可。
延迟队列生产原理
为保证消费者正常消费,如果优先队列头元素和当前放入元素相等,则说明当前元素消费的优先级高,重置准备消费的线程(leader)为null,唤醒消费者线程重新执行take方法逻辑。
手写一个Redis延迟队列
Redis延迟队列设计
延迟消息体设计
延迟消息体Message实现了Delayed接口,这样Java DelayQueue就知道什么时候取出消息体。
Redis延迟队列实现
RedisDelayQueue构造函数依赖redis操作缓存服务对象和目标队列名称(redis key)。
offer方法传入member(具体消息),delay(延迟时间),timeUnit(时间单位),然后封装成延迟消息体Message对象,放入Java DelayQueue中。
run方法是一个循环体,不断的从Java DelayQueue对象中获取消息体,然后放入redis对应的目标队列里。
延迟队列测试demo
控制台打印效果
思考
这种方案实现比较简单,使用的时候一定要谨慎,应用于延迟小,消息量不大的场景是没问题的,毕竟Java DelayQueue是占用内存的。另外也可以考虑利用Redis的sorted set 结构实现延迟队列,使用TimeStamp作为score,比如你的任务是要延迟5分钟,那么就在当前时间上加5分钟作为 score ,轮询任务每秒只轮询 score 小于等于 当前时间的 key即可,如果任务支持有误差,那么当没有扫描到有效数据的时候可以休眠对应时间再继续轮询。
灵感来袭,基于Redis的分布式延迟队列的更多相关文章
- 灵感来袭,基于Redis的分布式延迟队列(续)
背景 上一篇(灵感来袭,基于Redis的分布式延迟队列)讲述了基于Java DelayQueue和Redis实现了分布式延迟队列,这种方案实现比较简单,应用于延迟小,消息量不大的场景是没问题的,毕竟J ...
- [转载] 基于Redis实现分布式消息队列
转载自http://www.linuxidc.com/Linux/2015-05/117661.htm 1.为什么需要消息队列?当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消 ...
- PHP基于Redis实现轻量级延迟队列
延迟队列,顾名思义它是一种带有延迟功能的消息队列. 那么,是在什么场景下我才需要这样的队列呢? 一.背景 先看看一下业务场景: 1.会员过期前3天发送召回通知 2.订单支付成功后,5分钟后检测下游环节 ...
- Dyno-queues 分布式延迟队列 之 基本功能
Dyno-queues 分布式延迟队列 之 基本功能 目录 Dyno-queues 分布式延迟队列 之 基本功能 0x00 摘要 0x01 Dyno-queues分布式延迟队列 1.1 设计目标 1. ...
- Dyno-queues 分布式延迟队列 之 生产消费
Dyno-queues 分布式延迟队列 之 生产消费 目录 Dyno-queues 分布式延迟队列 之 生产消费 0x00 摘要 0x01 前情回顾 1.1 设计目标 1.2 选型思路 0x02 产生 ...
- Dyno-queues 分布式延迟队列 之 辅助功能
Dyno-queues 分布式延迟队列 之 辅助功能 目录 Dyno-queues 分布式延迟队列 之 辅助功能 0x00 摘要 0x01 前文回顾 0x2 Ack机制 2.1 加入Un-ack集合 ...
- 基于Redis的分布式锁真的安全吗?
说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...
- 基于redis的分布式锁的分析与实践
前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...
- 基于Redis的分布式锁到底安全吗(下)?
2017-02-24 自从我写完这个话题的上半部分之后,就感觉头脑中出现了许多细小的声音,久久挥之不去.它们就像是在为了一些鸡毛蒜皮的小事而相互争吵个不停.的确,有关分布式的话题就是这样,琐碎异常,而 ...
随机推荐
- linux记录每次登陆的历史命令
编辑/etc/profile,增加如下代码 #Record history operation USER_IP=`>/dev/null |awk '{print $NF}' |sed -e 's ...
- nginx图片过滤处理模块http_image_filter_module安装配置
http_image_filter_module是nginx提供的集成图片处理模块,支持nginx-0.7.54以后的版本,在网站访问量不是很高磁盘有限不想生成多余的图片文件的前提下可,就可以用它实时 ...
- LeetCode 题解 | 1. 两数之和
题目描述: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], t ...
- python xlwings Excel 内容截图
import xlwings as xw from PIL import ImageGrab def excel_save_img(path, sheet=0, img_name="1&qu ...
- Harbor镜像漏洞扫描
Harbor镜像漏洞扫描 闲聊:我们知道 镜像安全也是容器化建设中一个很重要的环节,像一些商业软件如:Aqua就很专业但是收费也是很昂贵的,今天我们介绍下Harbor自带的镜像扫描器. 一.安装最新版 ...
- mysql中用SQL增加、删除字段,修改字段名
CREATE TABLE `tuser` ( `id` int(11) NOT NULL, `name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ...
- Description Resource Path Location Type cvc-complex-type.2.4.c: The matching 解决问题
2017-03-02 10:08:03,112 [localhost-startStop-1] ERROR org.springframework.web.servlet.DispatcherServ ...
- CSS单位计算总结
CSS单位总结 公共部分css body { background-color: #000; color: skyblue; margin: 0; padding: 0; } body>div& ...
- ABP开发框架前后端开发系列---(16)ABP框架升级最新版本的经验总结
有一小段时间没有持续升级ABP框架了,最近就因应客户的需要,把ABP框架进行全面的更新,由于我们应用的ABP框架,基础部分还是会使用官方的内容,因此升级的时候需要把官方基础ABP的DLL进行全面的更新 ...
- Tomcat8优化--Apache JMeter测试
一.部署测试java web项目(压力测试环境搭建) 1.mysql环境 #切换到mysql目录 cd /usr/local/mysql #查看mysql环境 rpm -qa | grep -i my ...