定时任务方案实现与对比

news2024/10/7 3:20:53

定时任务分类

   定时任务分为分布式定时任务和单机定时任务两个大的方向,他们的适用场景不同。

   单机定时任务在单台计算机上运行,其执行结果和单台机器上的数据有关,如对本地机器的缓存做核对、清理日志等。它的 优点 是简单易用,无需额外的配置和部署;缺点是任务一般没有持久化机制,重启后有任务丢失的问题。

   分布式定时任务,将任务交由集群中的某个机器来执行,常用于需要在分布式环境下协同执行的任务,例如处理耗时较长的任务、数据同步、消息处理、超时关单等场景。它的优点是高可靠性、高可扩展性和分布式特性;缺点视具体的组件而定。

本地定时任务框架

   单机定时任务有 Timer、ScheduledExecutorService、SpringTask、SpringQuartz 等。Timer、ScheduledExecutorService 都无法使用 Cron 表达式指定任务执行的具体时间,灵活性不够,本文不做展开。

SpringTask

org.springframework.scheduling.annotation.Scheduled提供的属性如下:

/**
	 * A cron-like expression, extending the usual UN*X definition to include triggers
	 * on the second, minute, hour, day of month, month, and day of week.
	 * <p>For example, {@code "0 * * * * MON-FRI"} means once per minute on weekdays
	 * (at the top of the minute - the 0th second).
	 * <p>The fields read from left to right are interpreted as follows.
	 * <ul>
	 * <li>second</li>
	 * <li>minute</li>
	 * <li>hour</li>
	 * <li>day of month</li>
	 * <li>month</li>
	 * <li>day of week</li>
	 * </ul>
	 * <p>The special value {@link #CRON_DISABLED "-"} indicates a disabled cron
	 * trigger, primarily meant for externally specified values resolved by a
	 * <code>${...}</code> placeholder.
	 * @return an expression that can be parsed to a cron schedule
	 * @see org.springframework.scheduling.support.CronSequenceGenerator
	 */
	String cron() default "";

	/**
	 * A time zone for which the cron expression will be resolved. By default, this
	 * attribute is the empty String (i.e. the server's local time zone will be used).
	 * @return a zone id accepted by {@link java.util.TimeZone#getTimeZone(String)},
	 * or an empty String to indicate the server's default time zone
	 * @since 4.0
	 * @see org.springframework.scheduling.support.CronTrigger#CronTrigger(String, java.util.TimeZone)
	 * @see java.util.TimeZone
	 */
	String zone() default "";

	/**
	 * Execute the annotated method with a fixed period in milliseconds between the
	 * end of the last invocation and the start of the next.
	 * @return the delay in milliseconds
	 */
	long fixedDelay() default -1;

	/**
	 * Execute the annotated method with a fixed period in milliseconds between the
	 * end of the last invocation and the start of the next.
	 * @return the delay in milliseconds as a String value, e.g. a placeholder
	 * or a {@link java.time.Duration#parse java.time.Duration} compliant value
	 * @since 3.2.2
	 */
	String fixedDelayString() default "";

	/**
	 * Execute the annotated method with a fixed period in milliseconds between
	 * invocations.
	 * @return the period in milliseconds
	 */
	long fixedRate() default -1;

	/**
	 * Execute the annotated method with a fixed period in milliseconds between
	 * invocations.
	 * @return the period in milliseconds as a String value, e.g. a placeholder
	 * or a {@link java.time.Duration#parse java.time.Duration} compliant value
	 * @since 3.2.2
	 */
	String fixedRateString() default "";

	/**
	 * Number of milliseconds to delay before the first execution of a
	 * {@link #fixedRate} or {@link #fixedDelay} task.
	 * @return the initial delay in milliseconds
	 * @since 3.2
	 */
	long initialDelay() default -1;

	/**
	 * Number of milliseconds to delay before the first execution of a
	 * {@link #fixedRate} or {@link #fixedDelay} task.
	 * @return the initial delay in milliseconds as a String value, e.g. a placeholder
	 * or a {@link java.time.Duration#parse java.time.Duration} compliant value
	 * @since 3.2.2
	 */
	String initialDelayString() default "";

执行原理:

   ScheduledTaskRegistrar#afterPropertiesSet 方法中,默认初始化一个单线程的 ScheduledExecutorService 来执行任务。

   SpringTask 在 ScheduledAnnotationBeanPostProcessor#processScheduled 中解析和收集 Scheduled 注解中的参数;然后向 ScheduledTaskRegistrar 中添加对应类型的任务。

ScheduledExecutorService:

   总结起来就是通过线程池来执行任务;DelayedWorkQueue 作为阻塞队列,并排序任务定时执行;ScheduledFutureTask 记录任务定时信息,。

   ScheduledExecutorService 继承线程池,也是把任务提交给线程池执行,只不过它的任务类进行了扩展。
在这里插入图片描述

   ScheduledExecutorService 自定义了阻塞队列 DelayedWorkQueue 给线程池使用,它可以根据 ScheduledFutureTask 的下次执行时间来阻塞 take 方法,并且新进来的 ScheduledFutureTask 会根据这个时间来进行排序,最小的最前面。

   任务类 ScheduledFutureTask 继承 FutureTask 并扩展了一些属性来记录任务下次执行时间和每次执行间隔。同时重写了run方法重新计算任务下次执行时间,并把任务放到线程池队列中。
在这里插入图片描述

使用 spring task 的优缺点:

优点:

  • spring框架自带的定时功能,开启和定义定时任务非常容易,支持复杂的 cron 表达式,可以满足绝大多数单机版的业务场景。单线程执行任务时,当前次的调度完成后,再执行下一次任务调度。

缺点:

  • 默认单线程,如果前面的任务执行时间太长,对后面任务的执行有影响。
  • 不支持集群方式部署,提交的任务在单机内存中,可能出现任务丢失的情况

SpringQuartz

优点:

  • 默认是多线程异步执行,单个任务时,在上一个调度未完成时,下一个调度时间到时,会另起一个线程开始新的调度,多个任务之间互不影响。
  • 支持复杂的 cron 表达式
  • 它能被集群实例化,支持分布式部署。

缺点:

  • 相对于spring task实现定时任务成本更高,需要手动配置 QuartzJobBean 、 JobDetail和 Trigger 等。需要引入了第三方的 quartz 包,有一定的学习成本。
  • 没有内置 UI 管理控制台。
  • 不支持并行调度,不支持失败处理策略和动态分片的策略等。

代码案例

分布式定时任务框架

XXL-Job

在这里插入图片描述
   将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。

   将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。

调度中心

   自研调度组件(早期调度组件基于Quartz);一方面是为了精简系统降低冗余依赖,另一方面是为了提供系统的可控度与稳定性;

执行器

   执行器实际上是一个内嵌的Server,在项目启动时,执行器会通过 “@JobHandler” 识别Spring容器中“Bean模式任务”,以注解的value属性为key管理起来。

   “执行器”接收到“调度中心”的调度请求时,如果任务类型为“Bean模式”,将会匹配Spring容器中的“Bean模式任务”,然后调用其execute方法,执行任务逻辑。如果任务类型为“GLUE模式”,将会加载GLue代码,实例化Java对象,注入依赖的Spring服务(注意:Glue代码中注入的Spring服务,必须存在与该“执行器”项目的Spring容器中),然后调用execute方法,执行任务逻辑。

优缺点:

优点:

  • 有界面管理定时任务,支持弹性扩容缩容、动态分片、故障转移、失败报警等功能。
  • 支持在运行时动态创建任务( XxlJobHelper#submitCronTask),参见:xxl-job issue277

缺点:

  • 一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行。和 quartz 一样,通过数据库分布式锁,来控制任务不能重复执行
  • 调度中心HA(中心式):调度采用中心式设计,“调度中心”自研调度组件并支持集群部署,可保证调度中心HA。不同于 Elastic-Job 的去中心化设计, XXL-JOB 的这种设计也被称为中心化设计

官网-架构

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

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

相关文章

玩着3dmax把Python学了-01

3ds Max 2022以前的版本要借助Python的api来实现Python编程达到编辑绘图脚本的功能&#xff0c;但是好消息来了&#xff0c;3ds Max 2022 起&#xff0c;MaxPlus 不再作为 3ds Max 的 Python API 包含在内。而是3ds Max 将 Python 3.7 的标准版本包涵其中了&#xff0c;位于 [3…

MySQL监控告警及可视化:Zabbix+Percona PMP实现(Part II)

MySQL监控告警及可视化&#xff1a;ZabbixPercona PMP实现&#xff08;Part II&#xff09; PMP插件安装PMP监控脚本配置Web界面导入PMP模板 服务器清单如下&#xff1a; 服务器IP配置OS版本服务器角色172.16.175.x4c8gCentOS 7.7MySQL Server172.16.175.y4c8gCentOS 7.7Zabbi…

Python——基于YOLOV8的车牌识别(源码+教程)

目录 一、前言 二 、完成效果 三、 项目包 四、运行项目 &#xff08;教程&#xff09; 一、前言 YOLOv8LPRNet车牌定位与识别https://www.bilibili.com/video/BV1vk4y1E7MZ/ 最近做了有一个车牌识别的小需求&#xff0c;今天完成了&#xff0c;在此记录和分享 首先&#x…

NECCS|全国大学生英语竞赛C类|听力|短篇新闻|听写填空|16:40~17:10+17:30~18:10

目录 一、听写填空 1. 题型 2. 技巧 &#xff08;1&#xff09;利用间隙 浏览全文 积极预测 &#xff08;2&#xff09;边听边记 &#xff08;3&#xff09;注重检查 二、短篇新闻 1. 试题解读 2. 解题技巧 &#xff08;1&#xff09;预测要点&#xff0c;有的放矢 …

【五一创作】机械臂速成小指南(二十四):逆运动学的雅可比方法

&#x1f468;‍&#x1f3eb;&#x1f970;&#x1f973;需要机械臂相关资源的同学可以在评论区中留言哦&#x1f916;&#x1f63d;&#x1f984; 指南目录&#x1f4d6;&#xff1a; &#x1f389;&#x1f389;机械臂速成小指南&#xff08;零点五&#xff09;&#xff…

Redis消息队列

消息队列&#xff08;Message Queue&#xff09;&#xff0c;字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色&#xff1a; 消息队列&#xff1a;存储和管理消息&#xff0c;也被称为消息代理&#xff08;Message Broker&#xff09; 生产者&#xff1a;发送消…

【hello Linux】线程概念

目录 1. 线程概念的铺设 2. Linux线程概念 2.1 什么是线程 2.2 线程的优点 2.3 线程的缺点 2.4 线程异常 2.5 线程用途 3. Linux进程VS线程 4. Linux线程控制 4.1 POSIX线程库 4.2 创建线程 4.3 进程ID和线程ID 4.4 线程终止 4.5 线程等待 4.6 分离线程 Linux&#x1f337; 1…

FPGA时序约束(六)时序例外约束

系列文章目录 FPGA时序约束&#xff08;一&#xff09;基本概念入门及简单语法 FPGA时序约束&#xff08;二&#xff09;利用Quartus18对Altera进行时序约束 FPGA时序约束&#xff08;三&#xff09;时序约束基本路径的深入分析 FPGA时序约束&#xff08;四&#xff09;主时…

解除Word的编辑保护【简单版】

首先&#xff0c;我们遇到的情况是下图这样的&#xff1a; 点一下停止保护&#xff0c;是下图这样的&#xff1a; 开始解决&#xff1a; 第一种方式&#xff1a;另存为Word Xml 存好了&#xff0c; 打开如下图&#xff08;我用VS打开的&#xff0c;最好找个能够格式化代码的编…

C++---区间DP---棋盘分割(每日一道算法2023.5.2)

注意事项&#xff1a; 涉及到"矩阵/二维前缀和"的一些知识&#xff0c;建议先理解那篇文章。 题目&#xff1a; 将一个 88 的棋盘进行如下分割&#xff1a;将原棋盘割下一块矩形棋盘并使剩下部分也是矩形&#xff0c;再将剩下的部分继续如此分割&#xff0c;这样割了…

echarts数据可视化-动态柱状图

效果如下&#xff1a; 此处用的echarts柱状图为&#xff1a;Axis Align with Tick 本文的要讨论的内容&#xff1a; 1、柱状图样式修改 2、多数据的缩放展示 柱状图样式修改 // 数据 const city reactive([{ value: 335, name: 长沙 },{ value: 310, name: 武汉 },{ value: …

C++类和对象 ——构造函数

C拷贝构造函数详解 什么是拷贝构造函数&#xff1f;拷贝构造函数的特征默认拷贝构造函数为什么需要显示定义构造函数&#xff1f;拷贝构造函数的调用场景什么时候不需要自己定义拷贝构造函数 什么是拷贝构造函数&#xff1f; 在现实生活中&#xff0c;拷贝构造函数就好像我们上…

Linux服务器 容器化部署新版Jenkins

安装Docker 先安装yml yum install -y yum-utils device-mapper-persistent-data lvm2设置加速镜像&#xff08;阿里云镜像&#xff09; sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装docker yum -y install d…

智慧工厂人员定位系统源码,实现对工厂内的人车、物、料等的精确定位

智慧工厂人员定位系统源码 技术架构&#xff1a;Java vue spring boot 系统概述&#xff1a; 采用UWB定位技术&#xff0c;通过在厂区内布设一定数量的定位基站&#xff0c;实时精确地定位员工、车辆、物品上微标签位置&#xff0c;零延时地将人、车、物的位置信息显示在工厂…

数据结构(六)—— 二叉树(2)遍历

文章目录 递归三要素一、深度优先遍历&#xff08;前中后序&#xff09;1.1 递归遍历1.1.1 前序&#xff08;中左右&#xff09;1.1.2 中序&#xff08;左中右&#xff09;1.1.3 后序&#xff08;左右中&#xff09; 1.2 迭代遍历1.2.1 前序1.2.2 后序1.2.3 中序 二、广度优先遍…

创建前、中、后序二叉树

创建前、中、后序二叉树 一、前序二叉树二、中序二叉树二、后序二叉树 一、前序二叉树 规则&#xff1a;根->左->右 前序遍历结果&#xff1a;ABCDEFGHK 二、中序二叉树 规则&#xff1a;左->根->右 中序遍历结果&#xff1a;ABCDEFG 二、后序二叉树 规则&a…

浅尝ChatGPT使用之Python字典嵌套排序

一、背景 所负责的项目从v1.0升级到v2.0之后&#xff0c;发送到kafka的Json数据字段顺序和内容有所改变&#xff0c; v1.0版本推送数据样例&#xff1a; {"name": "小王子","author": "安托万德圣-埃克苏佩里&#xff08;1900-1944&#…

1.Hive基础

1.简介 作用&#xff1a;将结构化数据映射为一张表&#xff0c;并提供类sql功能 本质&#xff1a;将HQL转化成MapReduce程序 &#xff08;1&#xff09;Hive处理的数据存储在HDFS ​ &#xff08;2&#xff09;Hive分析数据底层的实现是MapReduce ​ &#xff08;3&#x…

keil5固件库版本的工程建立

keil5固件库版本的工程建立 一、一个文件夹&#xff0c;如图再建立4个文件夹 二、准库往上图四个文件夹里粘贴 从标准库里面把Libraries里面的两个文件夹全部复制到新建文件夹Libraries里面 三、来对新建的Libraries里面的两个文件夹进行更改 STM32F10x_StdPeriph_Driver这个…

ajax与json

title: 15 ajax与json date: ‘2023-3-29’ 从一个例子开始 传统的方式进行前后端交互是什么样子的&#xff1f; <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%> <html> <head><me…