定时任务框架

定时任务的框架有哪些

Timer,JDK自带的,比较简单,使用的时候,定义一个TimerTask,实现run方法,然后定义一个Timer类,调用timer.schedule(timerTask,1000,3000);
○ 缺点:单线程、无异常处理,如果执行时间太长或者任务执行异常,会影响其他任务调度
springboot 的 @Scheduled (Spring Task)
使用简单,在启动类上开启,EnableScheduling,然后在使用定时任务的方法上添加`@Scheduled(cron=“xxxxxxx”)
○ 优点:1.简单 2.比Timer准确一点 3.可以配置多线程
○ 缺点:1.无自带异常处理,2.设计上偏向单节点运行
Quartz 框架,是一个完全由Java编写的开源作业调度框架,这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂。
○ 优点:1.强大的调度功能 2.灵活的应用方式 3.支持持久化
○ 缺点:需要把任务信息持久化到业务数据库、和业务有耦合、并且表比较多
xxl-job:的组成角色:整体分为两个部分:调度中心执行器,调度中心:可以理解为服务端,需要单独部署,提供的UI界面来管理定时任务,负责发起调度,本身不承接业务逻辑。把调度和任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块。执行器:可以理解为客户端,需要跟我们实际开发的项目整合,负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。

下面着重介绍下Quartz以及xxl-job

Quartz

里面有几个核心的概念:Job(任务)表示我们定时要执行的业务逻辑,需要重写execute()方法,Trigger(触发器)表示什么时候执行,Scheduler(调度器)负责把Job和Trigger绑定在一起去执行,保证任务可以在正确的时间执行。
在这里插入图片描述
Job和Trigger关系:一个job可以有多个trigger;一个trigger只能有个一个job;
核心代码

private void openJob(Scheduler scheduler){try {//1.创建一个JobDetailJobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("job1", "group1").build();//2.触发器表达式对象CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/4 * * * * ?");//CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("30 25 16 * * ?");//3.准备一个触发器对象CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggergroup1").withSchedule(cronScheduleBuilder).build();//4.开始调度scheduler.scheduleJob(jobDetail,cronTrigger);} catch (SchedulerException e) {e.printStackTrace();} finally {}
}

通过代码可以看到几个重要的类:
● JobDetail: 真正的任务内容,任务本身是集成Job接口的,但是真正的任务是 JobBuilder通过反射的方式实例化的。
● Trigger: 触发器,定义任务应当开始的时间,主要分为两类 SimpleTrigger,CronTrigger,当前例子的就是简单触发器,CronTrigger主要用于 处理quartz表达式定义的任务,比如每个月20号,每个星期一之类的。
● Scheduler: 计划执行者,现在我们有了要做的内容(HelloJob),有了要做的时间 (下一分钟),接下来,就把这两个内容填充到计划任务Scheduler对象里面,到了时间它就可以自动运行了。

Quartz核心类与方法

暂停Job:------pauseJob(jobKey)

//通过JobName以及JobGroup获得JobKeyJobKey jobKey = JobKey.jobKey("123", JOB_GROUP_NAME);try {Scheduler scheduler = schedulerFactoryBean.getScheduler();scheduler .pauseJob(jobKey);} catch (SchedulerException e) {e.printStackTrace();}

恢复Job:-----resumeJob(jobKey)

//通过JobName以及JobGroup获得JobKey
JobKey jobKey = JobKey.jobKey("123", JOB_GROUP_NAME);
try {schedulerFactoryBean.getScheduler().resumeJob(jobKey);
} catch (SchedulerException e) {e.printStackTrace();
}

删除job------deleteJob(jobKey)/unscheduleJob(triggerkey)

方法一:
//通过JobName以及JobGroup获得JobKey
JobKey jobKey = JobKey.jobKey("123", JOB_GROUP_NAME);
try {schedulerFactoryBean.getScheduler().deleteJob(jobKey);
} catch (SchedulerException e) {e.printStackTrace();
}
方法二:
//通过triggerName获取TriggerKey
TriggerKey aaatrigger = TriggerKey.triggerKey("aaatrigger");
try {schedulerFactoryBean.getScheduler().unscheduleJob(aaatrigger);
} catch (SchedulerException e) {e.printStackTrace();
}

JobDetail

JobDetailJob实例提供了许多设置属性,以及JobDetailMap成员变量属性,它用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。

JobDetail属性

name:任务名称
group:任务所属组
jobClass:任务实现类
jobDataMap:传参的作用

JobExecutionContext

Scheduler调用一个Job,就会将JobExecutionContext传递给Jobexecute()方法;
Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。

JobDataMap

在进行任务调度时JobDataMap存储在JobExecutionContext中,非常方便获取
JobDataMap可以用来装载任务可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它
JobDataMap实现了JDKMap接口,并且添加了一些非常方便的方法用来存取基本数据类型

说明:
1、实际上,Quartz在进行调度器初始化的时候,会加载quartz.properties文件进行一些属性的设置,比如Quartz后台线程池的属性(threadCount)、作业存储设置等。它会先从工程中找,如果找不到那么就是用quartz.jar中的默认的quartz.properties文件。
2、Quartz存在监听器的概念,比如任务执行前后、任务的添加等,可以方便实现任务的监控。

XXL-JOB

quartz现有定时任务的缺点:
● 1.各个模块都需要使用QuartzJobConfig配置,调度逻辑和执行任务耦合在一起
● 2.定时任务缓存会影响配置修改
● 3.开关不方便
● 4.没有管理页面

XXL-JOB的优点(特性)

使用简单,支持集群部署;提供运维界面维护成本小;自带错误预警;相对elastic-job来说不需要额外的组件(zookeeper);支持调度策略;支持分片;故障转移 ;更适合分布式。

● 简单:支持通过Web页面对任务进行CRUD操作,支持动态修改任务状态、启动/停止任务,操作简单
● 任务分布式执行,任务”执行器”支持集群部署,支持弹性扩容缩容;
● 丰富的路由策略:包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等
● 任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务
● 任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试
● 任务失败告警;默认提供邮件方式失败告警,同时预留扩展接口,可方便的扩展短信、钉钉等告警方式
● 分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务

xxl-job的组成角色:

整体分为两个部分:调度中心 和 执行器
调度中心:可以理解为服务端,需要单独部署,提供的UI界面来管理定时任务,负责发起调度,本身不承接业务逻辑。把调度和任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块。
支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。
执行器:可以理解为客户端,需要跟我们实际开发的项目整合,负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;接收“调度中心”的执行请求、终止请求和日志请求等。任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑
总结:“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性。

三个文件

  • xxl-job-admin 调度中心
  • xxl-job-core 公共依赖
  • xxl-job-executor-samples 实例–执行器

任务详解

基础配置:
- 执行器:任务的绑定的执行器,任务触发调度时将会自动发现注册成功的执行器, 实现任务自动发现功能; 另一方面也可以方便的进行任务分组。每个任务必须绑定一个执行器, 可在 “执行器管理” 进行设置;
- 任务描述:任务的描述信息,便于任务管理;
- 负责人:任务的负责人;
- 报警邮件:任务调度失败时邮件通知的邮箱地址,支持配置多邮箱地址,配置多个邮箱地址时用逗号分隔;
触发配置:
- 调度类型:
无:该类型不会主动触发调度;
CRON:该类型将会通过CRON,触发任务调度;
固定速度:该类型将会以固定速度,触发任务调度;按照固定的间隔时间,周期性触发;
固定延迟:该类型将会以固定延迟,触发任务调度;按照固定的延迟时间,从上次调度结束后开始计算延迟时间,到达延迟时间后触发下次调度;
- CRON:触发任务执行的Cron表达式;
- 固定速度:固件速度的时间间隔,单位为秒;
- 固定延迟:固件延迟的时间间隔,单位为秒;
任务配置:
- 运行模式:
BEAN模式:任务以JobHandler方式维护在执行器端;需要结合 “JobHandler” 属性匹配执行器中任务;
GLUE模式(Java):任务以源码方式维护在调度中心;该模式的任务实际上是一段继承自IJobHandler的Java类代码并 “groovy” 源码方式维护,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务;
GLUE模式(Shell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 “shell” 脚本;
GLUE模式(Python):任务以源码方式维护在调度中心;该模式的任务实际上是一段 “python” 脚本;
GLUE模式(PHP):任务以源码方式维护在调度中心;该模式的任务实际上是一段 “php” 脚本;
GLUE模式(NodeJS):任务以源码方式维护在调度中心;该模式的任务实际上是一段 “nodejs” 脚本;
GLUE模式(PowerShell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 “PowerShell” 脚本;
- JobHandler:运行模式为 “BEAN模式” 时生效,对应执行器中新开发的JobHandler类“@JobHandler”注解自定义的value值;
- 执行参数:任务执行所需的参数;
高级配置:
- 路由策略:当执行器集群部署时,提供丰富的路由策略,包括;
FIRST(第一个):固定选择第一个机器;
LAST(最后一个):固定选择最后一个机器;
ROUND(轮询):;
RANDOM(随机):随机选择在线的机器;
CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;
LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;
FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;
BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;
- 子任务:每个任务都拥有一个唯一的任务ID(任务ID可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务ID所对应的任务的一次主动调度。
- 调度过期策略:
- 忽略:调度过期后,忽略过期的任务,从当前时间开始重新计算下次触发时间;
- 立即执行一次:调度过期后,立即执行一次,并从当前时间开始重新计算下次触发时间;
- 阻塞处理策略:调度过于密集执行器来不及处理时的处理策略;
单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
- 任务超时时间:支持自定义任务超时时间,任务运行超时将会主动中断任务;
- 失败重试次数;支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;

xxl-job框架的使用步骤:

1、从GitHub下载对应项目代码

在这里插入图片描述

2、将xxl-job-core编译成jar包,上传到远程仓库(执行器需要应用对应jar包)
3、调度中心部署:

(可以用Jenkins打包发布)
1)将xxl-job-master整体打成jar包(删除xxl-job-excutor-samples模块)
2)对应jar包生成容器镜像
3)在机器上面配置环境变量,然后直接启容器镜像

4、调度项目接入

1)pom文件添加依赖

<!-- xxl-job -->
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>${xxl.job.core.version}</version>
</dependency>

2)添加java配置及yaml配置

# xxl-job
xxl:job:### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"admin.addresses: http://127.0.0.1:8083/xxl-job-admin### xxl-job, access tokenaccessToken: jrU2XoTTq2VSuh5n0J83z40jbcZL1Yn1executor:### xxl-job executor appnameappname: xm-ds-executor### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is nulladdress:### xxl-job executor server-infoip:port: 9999### xxl-job executor log-pathlogpath: /data0/logs/xxl-job### xxl-job executor log-retention-dayslogretentiondays: 30

XxlJobConfig.java

@Bean
public XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;
}

3)代码改造
在原来的quartz代码基础上,加上注解即可。注意注解后面的JobHandler名称需要跟控制台一致。
日志如果要记录到远程记录上面,需要使用对应的日志方法 XxlJobHelper.log(“XXL-JOB, Hello World.”);

@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {XxlJobHelper.log("XXL-JOB, Hello World.");
}
5、调度中心配置任务触发详情

1)添加执行器(新应用接入,添加后需要过30s左右时间,机器会自动注册过来)
注:此处的AppName需要跟第四步的2)yaml文件里面的appname一致。名称是用于页面其他地方展示执行器的名称
在这里插入图片描述
2)创建任务
注:此处的执行器,选择上一步添加的执行器,然后填写任务描述、负责人、报警邮件(接收人),填写调度配置、任务配置(注解接入属于BEAN模式,JobHandler需要跟第四步的3)里面注解填写的JobHandler名称一致,填写高级配置(路由策略、调度过期策略、阻塞处理策略需谨慎选择),子任务ID一般为空,任务超时时间和失败重试次数根据业务需要填写
在这里插入图片描述
3)任务测试及启动
此处执行一次,相当于手动触发一次立即执行的任务。业务允许的情况下,最好执行一次测试下,看下是否有问题(可以看执行日志)
4)查看执行日志,看下执行是否正常
注:实际的日志是记录到对应的执行器服务器上面的文件的,所以如果执行器未注册到调度中心,日志是看不了的
在这里插入图片描述
5)运行报表,可以用于查看每天任务调度情况
在这里插入图片描述

参考:
https://www.xuxueli.com/index.html

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

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

相关文章

附加Numpy数组

参考&#xff1a;Append Numpy Array 引言 在数据科学和机器学习领域&#xff0c;处理大规模数据集是一项重要且常见的任务。为了高效地处理数据&#xff0c;numpy是一个非常强大的Python库。本文将详细介绍numpy中的一个重要操作&#xff0c;即如何附加&#xff08;append&a…

LeetCode:2867. 统计树中的合法路径数目(筛质数+ DFS Java)

目录 2867. 统计树中的合法路径数目 题目描述&#xff1a; 实现代码与思路&#xff1a; 筛质数 DFS 原理思路&#xff1a; 2867. 统计树中的合法路径数目 题目描述&#xff1a; 给你一棵 n 个节点的无向树&#xff0c;节点编号为 1 到 n 。给你一个整数 n 和一个长度为 …

西软云XMS operate XXE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

Jquery操作DOM对象

文章目录 目录 文章目录 本章目标 一.DOM操作分类 二.JQuery中的DOM操作 内容操作 属性值操作 节点操作 节点属性操作 节点遍历 总结 本章目标 使用Jquery操作网页元素使用JQuery操作文本与属性值内容使用JQuery操作DOM节点使用Jquery遍历DOM节点使用JQuery操作CSS-DOM 一…

WebServer -- 日志系统(下)

目录 &#x1f33c;整体思路 &#x1f382;基础API fputs 可变参数宏 __VA_ARGS__ fflush &#x1f6a9;流程图与日志类定义 流程图 日志类定义 &#x1f33c;功能实现 生成日志文件 && 判断写入方式 日志分级与分文件 &#x1f33c;整体思路 日志系统分两部…

无法调试MFC源码

VS无法调试MFC源码 起初 有时候就是这么无奈&#xff0c;MFC源码各种问题没有办法调试&#xff0c;可是又想看下代码如何调用&#xff0c;里面做了些什么&#xff0c;从哪儿调出&#xff0c;学习一下大神的思路什么的。整理一下有可能的原因。 检查生成代码设置 需要设置正…

04 Opencv图像操作

文章目录 读写像素修改像素值Vec3b与Vec3F灰度图像增强获取图像通道bitwise_not 算子对图像非操作 读写像素 读一个GRAY像素点的像素值&#xff08;CV_8UC1&#xff09; Scalar intensity img.at(y, x); 或者 Scalar intensity img.at(Point(x, y)); 读一个RGB像素点的像素值…

虚拟机看不到共享文件夹

johnjohn-virtual-machine:/mnt/hgfs$ cat /etc/issue Ubuntu 20.04.6 LTS \n \l 看下是否挂载 johnjohn-virtual-machine:/mnt/hgfs$ vmware-hgfsclient FPGAs_AdaptiveSoCs_Unified_2023.2_1013_2256 xilinx 取消挂载 johnjohn-virtual-machine:/mnt/hgfs$ sudo umount /mn…

kvm虚拟机修改网络模式

kvm修改网络模式可以直接使用virsh命令进行修改 一、查看主机 virsh list --all 二、查看需要修改主机的网络模式 virsh domiflist mysql 三、vim进行修改 cd /etc/libvirt/qemu/ vim mysql.xml 四、找到要修改的网卡部分 五、重新定义虚拟机 virsh define mysql_install.xml…

java工具类之解析地址

输出 代码实现 import java.util.regex.Matcher; import java.util.regex.Pattern;public class AddressResolutionUtil {/*** 解析地址* author ys* param address* return*/public static String addressResolution(String address){String regex"(?<province>…

Java的编程之旅32——继承与多态的联合使用

模拟USB设备接入电脑 1.首先建立一个名为“USB”的抽象类 public abstract class USB {public abstract void On();public abstract void Off(); }这是一个抽象类USB&#xff0c;表示一个USB设备。 该类有两个抽象方法On()和Off()&#xff0c;分别表示打开和关闭USB设备。 由…

javaee教程郑阿奇,一线互联网架构师筑基必备技能之Java篇

一、什么情况下会发生栈内存溢出&#xff1f; 1、栈是线程私有的&#xff0c;栈的生命周期和线程一样&#xff0c;每个方法在执行的时候就会创建一个栈帧&#xff0c;它包含局部变量表、操作数栈、动态链接、方法出口等信息&#xff0c;局部变量表又包括基本数据类型和对象的引…

【GameFramework框架内置模块】6、实体(Entity)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录&#xff1a; https://blog.csdn.net/q7…

K 个一组翻转链表 力扣

【玩转校招算法面试】第三天&#xff1a;链表中的节点每k个一组翻转&#xff08;动画演示、手写 Java 代码、详细注释、LeetCode 高频算法题&#xff09;_哔哩哔哩_bilibili 初始状态&#xff1a;1 -> 2 -> 3&#xff0c;pre null, cur 1保存当前节点的下一个节点&…

并查集基础,死去的回忆突然攻击我

并查集普及【模板】并查集 - 洛谷 #include<iostream> #include<cstring> #include<queue> #include<vector> #include<algorithm> using namespace std; #define int long long typedef pair<int,int> PII; #define xx first #define y…

TypeScript 中类的理解及应用场景

&#x1f469; 个人主页&#xff1a;不爱吃糖的程序媛 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、CSDN内容合伙人&#xff0c;专注于前端各领域技术&#xff0c;成长的路上共同学习共同进步&#xff0c;一起加油呀&#xff01; ✨系列专栏&#xff1a;前端…

瑞_23种设计模式_组合模式

文章目录 1 组合模式&#xff08;Composite Pattern&#xff09;1.1 介绍1.2 概述1.3 组合模式的结构1.4 组合模式的分类1.5 组合模式的优点1.6 组合模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 &#x1f64a; 前言&#xff1a;本文章为瑞_系列…

TP6上传图片到OSS(记录贴)

1&#xff0c;先安装&#xff0c;我使用composer安装 在项目的根目录运行composer require aliyuncs/oss-sdk-php 2,安装成功以后vendor目录下可以看到如图&#xff1a; 3&#xff0c;上传图片代码如下&#xff1a; <?php namespace app\controller;use app\BaseControll…

1、docker入门

文章目录 1、tocker简介2、tocker的安装&环境配置2、配置阿里云镜像3、基本命令1、镜像命令2、docker基本命令3、镜像基本命令4、Docker 容器常用命令 1、tocker简介 新一代的虚拟化技术 2、tocker的安装&环境配置 uname -r1、首先查看liunx的内核 yum update -y2、更…

生成voc格式数据集

数据集存放格式&#xff1a;&#xff08;Annotations文件夹放标注的xml文件&#xff0c;JPEGImages文件夹放标注的图片&#xff09; 运行代码&#xff1a; import os import random import xml.etree.ElementTree as ETimport numpy as npdef get_classes(classes_path):with …