delayQueue实现

完整实现-通过DelayQueue实现延时任务 它的缺点就是所有的操作都是基于应用内存的,一旦出现应用单点故障,可能会造成延时任务数据的丢失。如果订单并发量非常大,因为DelayQueue是无界的,订单量越大,队列内的对象就越多,可能造成OOM的风险。需要说明的是,这里的while-true循环的延时任务处理时顺序执行的,在订单并发量比较大的时候,需要考虑异步处理的方式完成订单的关闭操作。使用DelayQueue实现延时任务非常简单,而且简便,全部都是标准的JDK代码实现,不用引入第三方依赖(不依赖redis实现、消息队列实现等),非常的轻量级。 阅读详情
需求背景
  • 用户下订单成功之后隔20分钟给用户发送上门服务通知短信
  • 订单完成一个小时之后通知用户对上门服务进行评价
  • 业务执行失败之后隔10分钟重试一次

    类似的场景比较多 简单的处理方式就是使用定时任务 假如数据比较多的时候 有的数据可能延迟比较严重,而且越来越多的定时业务导致任务调度很繁琐不好管理。

序号

方案

实现原理

优点

缺点

1

java DelayQueue

wait-notify机制不引入其他服务依赖,wait-notify机制,不做polling,不会浪费cpu。数据保存在JVM内存中,当应用重启会造成数据丢失,或者数据量大时造成DelayQueue过大。
2

RabbitMQ 死信队列

利用ttl 以及DLE (Dead Letter Exchanges)可以模拟出延迟队列

开源,现成的稳定的实现方案每个延迟时间需要单独一个队列(5分钟延时是一个,10分钟延迟是另外一个)。除此以外,使用较复杂,对开发者有一定的要求。
3

redis zset

使用ZSET做优先队列,按照Score维持优先级

设定轮询,每分钟轮询一次zset,找出score小于当前秒数的数据,进行处理,然后将key在zset内删除

比较简单,支持持久化比较简陋的延时队列,有意外报错的话,大不了就多轮询几次。或者等人发现了再解决,也没有ack机制,所以也是挺不靠谱的,使用在不太重要的地方还行
4

自研DelayQueue

执行过程:

参数说明:

  • Topic:一组相同类型Job的集合(队列)。供消费者来订阅。
  • Id:Job的唯一标识。用来检索和删除指定的Job信息。
  • Delay:Job需要延迟的时间。单位:秒。(服务端会将其转换为绝对时间)
  • Body:Job的内容,供消费者做具体的业务处理,以json格式存储。
  • callBack:回调接口地址。使用http协议,该地址是一个url。

存储结构

名称

redis类型

保存数据格式

delayJob状态

FailedDelayJob状态

DelayQzsetjob--->scorepublishedN/A
ReadyQhash tablejobId--->jobreadyready
FailedDelayQzsetjob--->scoreN/Apublished

状态转换说明:

1. 客户端publish一个job,首先会被保存到delayQ中,此时状态为published(DelayJob);

2. 超时后,会从delayQ中取出,放入ReadyQ中,状态为Ready(DelayJob);

3 回调成功,则删除readyQ状态是deleted(DelayJob);

4 回调失败,DelayedJob 变为FailedDelayJob(transfer)删除readyQ信息状态为published(FailedDelayJob);

5.FailedDelayJob超时,会从FailedDelayQ删除,放入ReadyQ,状态为Ready(FailedDelayJob);

6.回调成功,则删除readyQ,状态是deleted(FailedDelayJob);

7.回调失败,小于重试次数,则再次transfer,删除readyQ信息,状态为published(FailedDelayJob);

8.回调失败,超过重试次数,则归档,发提示短信,同时删除readyQ&数据字典信息,deleted(FailedDelayJob)。

DelayJob和FailedDelayJob转换:

 

基于DelayQueue实现的延时队列 当然监听的方法其实还有很多,不过同学们在实现队列的时候不要觉得实现了就好了,要去思考如何去保证数据的持久化,保证数据不会不会丢失。别急 这个只是个Demo嘛,如果需要使用在项目中可以写一个监听器去实时监听该延时队列。方法一样 都是在Spring Boot应用程序在启动后,对。该文章,我们这次主要是来实现基于。在控控制台中每隔1秒打印一行数据。通过timer定时定频率去获取。创建一个延时队列的生产者。定义一个延时队列的消费者。我这边暂时就只讲3种。 阅读详情

相关推荐

利用DelayQueue和Redis实现订单自动取消功能

延迟队列是一种支持元素按延迟时间出队的数据结构,它允许我们推迟任务的执行,直到达到预定的延迟时间。在Java中,DelayQueue实现了接口,通过内部使用优先队列来维护元素的顺序,可以有效地对任务进行延迟处理。DelayQueue是线程安全的,非常适合用于执行定时任务的场景。延迟队列,顾名思义,是一种允许元素延迟一段时间被取出的队列。与传统的先进先出(FIFO)队列不同,延迟队列的元素会在设定的延迟时间之后才会成为可获取的状态。这种队列特别适合于需要延迟处理或定时执行的任务场景。

weixin_42466857的博客 1135

Java 延迟队列 DelayQueue 的原理

一、什么是延迟队列(DelayQueue)? DelayQueue 是 Java 并发包 java.util.concurrent 下的一个 Class,其官方定义如下所示。 /** * An unbounded {@linkplain BlockingQueue blocking queue} of * {@code Delayed} elements, in which an element can only be taken * when it

长安明月的博客 1万+

从零到一:STM32G431的DSP库集成与FFT实战避坑指南

本文详细介绍了在STM32G431微控制器上集成CMSIS-DSP库并进行FFT实战开发的完整流程。重点解析了通过CubeMX和Keil环境配置DSP库的关键步骤、编译器宏定义陷阱及解决方案,并提供了FFT算法优化、内存管理及常见问题诊断的实用技巧,帮助开发者高效实现嵌入式信号处理应用。

oauth7security的博客 771

DelayQueue延时队列操作实例

DelayQueue延时队列,当队列中的元素到达延迟时间时才会被取出。队列元素会按照最终执行时间在队列中进行排序。最近刚学,本篇先给出一个实际使用的例子。 首先队列对象当然就是DelayQueue。而队列元素则需要实现Delayed这个接口,并实现该接口compareTo方法和getDelay方法。首先定义该元素及其属性。class DelayTask implements Delayed {

8823

MacOS上如何修改jupyter book的默认打开地址以及如何复制文件路径

记点笔记,才换新系统小半年,还是不太熟悉,所以记录一下笔记,感觉之后也会用到,希望能帮到你们。主要内容是:修改jupyter的默认地址以及复制文件路径。

魔仙的博客 1978

ADS使用Smith圆图进行阻抗匹配

在处理RF系统的实际应用问题时,总会遇到一些非常困难的工作,对各部分级联电路的不同阻抗进行匹配就是其中之一。一般情况下,需要进行匹配的电路包括天线与低噪声放大器(LNA)之间的匹配、功率放大器输出(RFOUT)与天线之间的匹配、LNA/VCO输出与混频器输入之间的匹配。匹配的目的是为了保证信号或能量有效地从“信号源”传送到“负载”。 阻抗匹配(impedance matching) 信号源内阻与所接传输线的特性阻抗大小相等且相位相同,或传输线的特性阻抗与所接负载阻抗的大小相等且相位相同,分别称为传输线的输

红茶绿茶和奶茶的博客 3万+

Delay 延时函数

procedure Delay(MSecs: Longint); //延时函数,MSecs单位为毫秒(千分之1秒) var FirstTickCount,Now:Longint; begin FirstTickCount := GetTickCount(); repeat Application.ProcessMessages; Now := GetTickCount(); until (Now - FirstTickCount >= MSecs)

期待下集是个可爱梦儿 2601

【Unity程序技巧】Unity中单例模式管理器

单例模式(Singleton Pattern)是 最简单的设计模式之一

秩沅 1659

【物联网学习】(五)ESP8266学习——Delay

ESP8266也有自带的延时函数,但是由于是基于内核回调的方式,系统有可能其他任务会打断延时,因此有时这个延时函数可能不准。 相关函数如下: 如何自己编辑一个属于自己的函数呢? 前面那个ICACHE_FLASH_ATTR 是固定的格式,后面是我们的函数名,其他和C语言一样。 这是一个毫秒延时函数。调用系统的是微秒延时函数。 在while循环里记得喂狗防止复位。 ...

Q小鑫 1937

MFC Windows 程序设计[105]之彩色滚动条(附源码)

MFC是微软公司提供的一个类库(class libraries),用以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。有很多初学MFC的小伙伴们都觉得MFC比较难学,看书吧,看了就忘了,网上的一些教程又是写的含糊不清,故而学习起来很吃力...... 故此,本专栏亲自研究,实践,由易到难,层层深入,将调试过程中所遭所遇进行详细讲解,注意事项进行一一列举,希望能够帮助到各位初学MFC的小伙伴,避免走弯路,费时费力。

hnjzfwy的博客 518

异步处理优化:多线程线程池与消息队列的选择与应用

本文讨论了两种常见的异步处理方式:多线程线程池和消息队列(MQ)。通过将非核心逻辑异步化,可以提升系统的性能和响应速度。多线程线程池适用于本地并发任务,适合需要快速响应的场景,但无法处理跨服务任务。消息队列则适用于分布式系统,能够解耦服务并保证任务的可靠性和顺序性,适合处理高并发和高可靠性要求的任务。文章提供了实际代码示例,帮助开发者根据业务需求选择合适的异步处理方式。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 170万+

DelayQueue实现原理

DelayQueue实现原理

SO_zxn的博客 1201

深度剖析XY2-100与SL2-100协议:解锁激光打标核心技术密码

XY2-100和SL2-100是激光打标领域的两种核心控制协议。XY2-100协议采用串行通信,指令集简单,适合常规打标任务,具有成本优势;SL2-100协议支持更高速率(1Mbps以上),具备曲线插补等高级指令,在精密加工领域表现突出。两者的主要差异体现在数据传输(帧结构、速率)、指令集(功能、数量)、参数调节(范围、精度)和错误处理机制等方面。实际应用中,XY2-100适合简单图形的大批量生产,SL2-100更胜任复杂曲面的高精度加工。选择时需综合考虑打标需求、设备兼容性和成本因素,未来两种协议将持续优

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 959

使用DelayQueue实现延迟任务

有时候,我们需要在当前时间点往后延迟一定时间,再执行任务,该怎么实现呢?

qq_30166465的博客 1343

Python 爬虫实战:爬取 GitHub 热门项目(星数 / 语言 / 作者)

本文系统介绍了使用Python爬虫技术获取GitHub热门项目数据的完整方案。通过分析GitHub Trending页面和官方API两种数据源,详细讲解了HTML解析、JSON数据处理、反爬应对策略等关键技术。采用requests、BeautifulSoup、pandas等工具链,实现了项目信息(名称、星数、语言等)的结构化爬取,并配套数据清洗、统计分析及可视化功能。特别强调遵守GitHub API使用规范,包括Token认证、请求频率控制等合规要求。该方案为开发者提供了一种高效、合法的数据采集方法,适用于

2503_91057718的博客 2346

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

完整实现 - 通过 DelayQueue 实现延时任务

一、DelayQueue 的应用原理二、订单延时任务的实现三、订单处理四、优缺点实现延时任务有很多的方法,网上关于延时任务的实现的文章已经不少了。比如:实现延时任务的 10 种方法等等。但是这些文章基本上都是将方法大概的列举一下,给出部分示例代码,对于有经验的老程序员可能一看就知道该怎么去把它实现完整,但是对于初学者来说不够友好。所以,。小概念:什么是延时任务?举个例子:你买了一张火车票,必须在 30 分钟之内付款,否则该订单被自动取消。

AS011x的博客 254

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

DelayQueue实现延迟队列

public class Q { public static void main(String[] args) throws Exception { DelayQueue<Order> orders = new DelayQueue<>(); Order order1 = new Order(1000, "1x"); ...

weixin_30782331的博客 96

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

DelayQueue实现延迟任务

Java使用DelayQueue实现延迟操作

weixin_45751763的博客 628

Springboot使用DelayQueue实现订单自动取消

DelayQueue小结 DelayQueue是一个有序的无界BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象在到期时才能从队列中取走。 DelayQueue只能添加实现了Delayed接口的对象,不能将null元素放置到这种队列中 BlockingQueue中add,offer,put方法区别 add 将指定的元素插入到此队列中,在成功时返回 true,如果当前没有可用空间,则抛出 IllegalStateException,该方式为非阻塞添加。 offer 将指定元素

田间稻草人 1499

DelayQueue学习及定时任务实现

延迟队列DelayQueue DelayQueue概念 DelayQueue是一个***无界***的***BlockingQueue(阻塞队列)***,队列中的元素是以到期时间进行排序的,只有到期的元素才能被取出。 扩展 无界队列: 简单来讲,无界队列就是指,当队列满了之后,如果又新增元素,队列会自动扩容;举一反三,有界队列就是队列容量固定不变。 阻塞队列: 简单来讲,阻塞队列就是指,当队列元素为空,获取元素的线程会等待队列变为非空,除非线程关闭;队列满时,添加元素的线程也会等待队列可用。同理,

V_A_L的博客 444

如何通过DelayQueue实现延时任务

使用DelayQueue实现延时任务非常简单,而且简便,全部都是标准的JDK代码实现,不用引入第三方依赖(不依赖redis实现、消息队列实现等),非常的轻量级。BlockingQueue即阻塞队列,java提供的面向多线程安全的队列数据结构,当队列内元素数量为0的时候,试图从队列内获取元素的线程将被阻塞或者抛出异常。需要说明的是,这里的while-true循环的延时任务处理是顺序执行的,在订单并发量比较大的时候,需要考虑异步处理的方式完成订单的关闭操作。当用户下单的时候,将订单下单任务放入延时队列。

Java_ttcd的博客 615

基于DelayQueue实现的带失效时间的缓存

import java.util.concurrent.DelayQueue; import java.util.concurrent.atomic.AtomicInteger; /** * @Auther: ZhangShenao * @Date: 2019/2/27 18:38 * @Description:缓存实现,可自动移除过期的缓存项 */ public class Sched...

weixin_34452850的博客 841

DelayQueue实现订单的定时取消

当订单定时取消需要修改数据库订单状态,但是怎么确定订单什么时候应该改变状态,解决方案有下面两种: 第一种,写个定时器去每分钟扫描数据库,这样更新及时,但是如果数据库数据量大的话,会对数据库造成很大的压力。 第二种,创建订单的时候再订单表里面创建一条记录,然后把这条记录保存到DelayQueue队列里面,并且用一个子线程不断地轮训这个出队的订单。然后进行订单状态修改的状态。 下面是这个方式的实现

zj972535075的专栏 1万+

利用DelayQueue实现延迟任务

JDK自带DelayQueue 是一个支持延时获取元素的阻塞队列, 内部采用优先队列 PriorityQueue 存储元素,同时元素必须实现 Delayed 接口;在创建元素时可以指定多久才可以从队列中获取当前元素,只有在延迟期满时才能从队列中提取元素。DelayQueue属于排序队列,它的特殊之处在于队列的元素必须实现Delayed接口,该接口需要实现compareTo和getDelay方法。getDelay方法:获取元素在队列中的剩余时间,只有当剩余时间为0时元素才可以出队列。

Dack的博客 442
上一篇: rabbitMQ使用方案
下一篇: 垃圾收集器CMS换G1
杜引强
博客等级 码龄13年 806粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值