延时任务的解决方案

news2024/11/21 2:37:21

延时任务的解决方案

  • 1.数据库轮询
  • 2. JDK的延迟队列
  • 3.netty时间轮算法
  • 4.使用消息队列

1.数据库轮询

该方案通常是在小型项目中使用,即通过一个线程定时的去扫描数据库,通过订单时间来判断是否有超时的订单,然后进行update或delete等操作

代码示例:

select * from '表名' where '时间字段' < '数据库存储的时间戳' and status = '未执行'
while(true){
	sql;
	Thread.sleep(1000);
}

1.优点:简单易行,支持集群操作

2.缺点:

  • 对服务器内存消耗大
  • 存在延迟,比如你每隔3分钟扫描一次,那最坏的延迟时间就是3分钟
  • 假设你的订单有几千万条,每隔几分钟这样扫描一次,数据库损耗极大

2. JDK的延迟队列

该方案是利用JDK自带的DelayQueue来实现,这是一个无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素,放入DelayQueue中的对象,是必须实现Delayed接口的

在这里插入图片描述
代码示例:

public class JdkDelayQueue {

    public static void main(String[] args) throws Exception{
        DelayQueue<MyDelayed> delayQueue = new DelayQueue();
        delayQueue.add(new MyDelayed("Andy",5, TimeUnit.SECONDS));
        delayQueue.add(new MyDelayed("Andy_1",10, TimeUnit.SECONDS));

        for (;;){
            // 没有队列就就会阻塞
            MyDelayed take = delayQueue.take();
            take.excutue();
        }

    }

    static class MyDelayed implements Delayed {

        private String name;

        private long startTime;
        public MyDelayed(String name, long delayTime, TimeUnit unit) {
            this.name = name;
            // 当前时间毫秒值
            long currentTime = System.currentTimeMillis();
            // 时间转换为毫秒值
            long convert = TimeUnit.MILLISECONDS.convert(delayTime, unit);
            // 任务真正的执行时间
            this.startTime = currentTime + convert;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            long currentTime = System.currentTimeMillis();
            if(startTime <= currentTime){
                return 0;
            }
            long nextTime = startTime - currentTime;
            return unit.convert(nextTime, TimeUnit.MICROSECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
            MyDelayed prx = (MyDelayed) o;
            MyDelayed next = this;
            if (prx.startTime < next.startTime) {
                return 1;
            } else if (prx.startTime > next.startTime){
                return -1;
            }
            return 0;
        }
        public void excutue(){
            System.out.println(name + "任务执行");
        }

    }
}

1.优点:效率高,任务触发时间延迟低

2.缺点:

  • 服务器重启后,数据全部消失,怕宕机
  • 集群扩展相当麻烦
  • 因为内存条件限制的原因,比如下单未付款的订单数太多,那么很容易就出现OOM异常
  • 代码复杂度较高

3.netty时间轮算法

时间轮算法可以类比于时钟,如上图箭头(指针)按某一个方向按固定频率轮动,每一次跳动称为一个 tick

在这里插入图片描述
这样可以看出定时轮由个3个重要的属性参数,ticksPerWheel(一轮的tick数),tickDuration(一个tick的持续时间)以及 timeUnit(时间单位),例如当ticksPerWheel=60,tickDuration=1,timeUnit=秒,这就和现实中的始终的秒针走动完全类似了。

如果当前指针指在1上面,我有一个任务需要4秒以后执行,那么这个执行的线程回调或者消息将会被放在5上。那如果需要在20秒之后执行怎么办,由于这个环形结构槽数只到8,如果要20秒,指针需要多转2圈,位置是在2圈之后的5上面(20 % 8 + 1)

1.优点:效率高,任务触发时间延迟时间比delayQueue低,代码复杂度比delayQueue低

2.确定

  • 服务器重启后,数据全部消失,怕宕机
  • 集群扩展相当麻烦
  • 因为内存条件限制的原因,比如下单未付款的订单数太多,那么很容易就出现OOM异常

4.使用消息队列

在这里插入图片描述

我们可以采用RabbitMQ的延时队列,RabbitMQ具有以下两个特性,可以实现延迟队列

  • RabbitMQ可以针对Queue和Message设置 x-message-ttl,来控制消息的生存时间,如果超时,则消息变为dead letter
  • RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可选)两个参数,用来控制队列内出现了dead letter,则按照这两个参数重新路由

1.优点:高效,可以利用rabbitmq的分布式特性轻易的进行横向扩展,消息支持持久化增加了可靠性。

2.缺点:本身的易用度要依赖于RabbitMq的运维,因为要引用RabbitMq,所以复杂度和成本变高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1375085.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯练习题(二)

&#x1f4d1;前言 本文主要是【算法】——蓝桥杯练习题&#xff08;二&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 …

关于CAD导入**地球的一些问题讨论

先上示例: 上图是将北京王佐停车场的红线CAD图导入到图新地球效果,如果看官正是需要这样的效果,那么请你继续往下看,全是干货! 在地球中导入CAD图可以做为电子沙盘。对于工程人来说,是极有帮助的。以前一直用谷歌地球,大约在2020年左右,就被和谐了。当时感觉挺可惜的。…

基于OpenMV与STM32的数据通信项目(代码开源)

前言&#xff1a;本文为手把手教学 OpenMV 与 STM32 的数据通信项目教程&#xff0c;本教程使用 STM32F103C8T6 与 OpenMV 进行操作。 OpenMV 是非常强大的计算机视觉实现工具&#xff0c;自身提供了非常多的视觉项目案例&#xff0c;编程与使用门槛极低。为了进一步增强作品的…

【阅读笔记】Chain of LoRA

一、论文信息 1 论文标题 Chain of LoRA: Efficient Fine-tuning of Language Models via Residual Learning 2 发表刊物 arXiv2023 3 作者团队 Department of Computer Science, Princeton University School of Computer Science and Engineering, Nanyang Technologic…

MySQL基础笔记(3)DML数据操作语句

顾名思义&#xff0c;全称是数据操作语言&#xff0c;用来对数据库中表的数据记录进行增删改操作~ 目录 一.添加数据 1.给指定字段添加数据 2.给全部字段添加数据 3.批量添加数据 二.修改数据 三.删除数据 一.添加数据 1.给指定字段添加数据 insert into 表名 (字段名…

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测 目录 区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CNN-BiLSTM-KDE多…

【开源】基于JAVA语言的婚恋交友网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新闻管理模块2.4 相亲大会管理模块2.5 留言管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 会员信息表3.2.2 新闻表3.2.3 相亲大会表3.2.4 留言表 四、系统展示五、核心代码5.…

第8章-第2节-Java中流的简单介绍

1、什么是流 我们可以先想象水流是怎样的&#xff1f;溪水不断流动&#xff0c;最终融入大海&#xff1b;我们今天的学习IO其实如同水流一样&#xff0c;当我们读取文件信息或者写入信息时&#xff0c;如同水流一样&#xff0c;不断读取或者写入&#xff0c;直到业务流程结束。…

【DolphinScheduler】datax读取hive分区表时,空分区、分区无数据任务报错问题解决

问题背景&#xff1a; 最近在使用海豚调度DolphinScheduler的Datax组件时&#xff0c;遇到这么一个问题&#xff1a;之前给客户使用海豚做的离线数仓的分层搭建&#xff0c;一直都运行好好的&#xff0c;过了个元旦&#xff0c;这几天突然在数仓做任务时报错&#xff0c;具体报…

Cylinder3D论文阅读

Cylindrical and Asymmetrical 3D Convolution Networks for LiDAR Segmentation&#xff08;2020年论文&#xff09; 作者&#xff1a;香港中文大学 论文链接&#xff1a;https://arxiv.org/pdf/2011.10033.pdf 代码链接&#xff1a;https://github.com/xinge008/Cylinder3D …

基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的课程答疑系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

e2studio开发磁力计LIS2MDL(2)----基于中断信号获取加速度数据

三轴加速度计LIS2DW12开发.2--轮基于中断信号获取加速度数据 概述视频教学样品申请源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback …

如何计算指标波动贡献率?(附Pandas实现)

大家好&#xff0c;我是阿粥 “为什么这个月销售额提升了30%&#xff1f;” “为什么转化率又降了&#xff0c;同比竟然降低了42%&#xff0c;什么原因导致的呢&#xff1f;” 这些都是数据分析师在工作中经常会遇到的问题&#xff0c;甚至有些基础岗的数据分析师要花80%以上的…

FineBI实战项目一(14):订单销售总数分析开发

点击添加组件按钮&#xff0c;打开组件页面。 设置组件的属性&#xff0c;比如图标样式&#xff0c;指针值&#xff0c;目标值、颜色、大小、标签等。 点击下方切换到仪表盘。 点击仪表板中的左上方组件&#xff0c;添加组件到仪表盘。 编辑标题 第一个组件成功添加到仪表板。

一包多语言——使用FontForge合并字体

大家好&#xff0c;我是阿赵。   比较多游戏做了一个游戏包里面包含了多种语言&#xff0c;可以游戏内切换。这里分享一个合并多种语言字体的方法。 一、遇到的问题 假设我们游戏需要同时显示简体中文、泰文、老挝文三种语言。 解决方案有多种&#xff1a; 1、准备多种字体 …

Linux学习记录——삼십구 数据链路层协议

文章目录 1、了解数据链路层2、认识以太网3、认识MAC地址4、以太网报文5、局域网通信原理1、基本原理2、数据碰撞3、交换机4、ARP协议5、RARP协议6、局域网中间人 6、DNS&#xff08;简单介绍&#xff09;7、ICMP协议1、报文2、traceroute命令 7、NAT技术1、基本过程2、NAPT3、…

springboot基于Web的社区医院管理服务系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括社区医院管理服务系统的网络应用&#xff0c;在外国线上管理系统已经是很普遍的方式&#xff0c;不过国内的管理系统可能还处于起步阶段。社区医院管理服务系统具有社区医院信…

你了解计算机网络的发展历史吗?

1.什么是计算机网络 计算机网络是指将一群具有独立功能的计算机通过通信设备以及传输媒体被互联起来的&#xff0c;在通信软件的支持下&#xff0c;实现计算机间资源共享、信息交换或协同工作的系统。计算机网络是计算机技术与通信技术紧密结合的产物&#xff0c;两者的迅速发展…

Vue3组件库 -- element plus 树形选择器组件怎样显示已有的树形菜单?

<el-tree-selectv-model"form.topmneu":data"tableData":props"{ label: title, value: id }":render-after-expand"false"style"width: 100%"check-strictly/> 添加 :props "{ lable : 字段名 , value: 字段…

【计算机网络】TCP原理 | 可靠性机制分析(三)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程、计算机网络的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目…