Quartz任务调度框架

2024-09-02 13:20
文章标签 框架 quartz 任务调度

本文主要是介绍Quartz任务调度框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、介绍
  • 二、使用步骤
    • 1.创建maven工程,添加依赖
    • 2.创建任务
    • 3.启动任务
  • 三、基本实现原理
    • 1. Scheduler任务调度器
    • 2. Triggers触发器
      • 2.1 SimpleTrigger
      • 2.2 CronTirgger
    • 3. Misfire策略
    • 4 任务Job
      • 4.1 Job
      • 4.2 JobDetail
      • 4.3 JobDataMap


前言

最近跟的一个系统需要实时监控主机的应用进程以及存储空间等,实时生成告警提醒,这就需要在规定的时间去触发消息提醒功能,在这里主要也是用到了Quartz来调度任务的。


一、介绍

Quartz作为 Spring 默认的调度框架,与 Spring 集成实现灵活可配置的调度功能,此外其支持多种调度方法,应用方式灵活,并具有分布式和集群能力。
应用场景:

  • 驱动流程:比如在确定时间后根据任务完成情况触发一个警告并通知
  • 系统维护:在具体时间点调度一个数据从数据库转到xml文件中
  • 在应用中提供消息提醒服务

二、使用步骤

1.创建maven工程,添加依赖

下载quartz的jar包,导入依赖

<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version>
</dependency>

2.创建任务

(1)创建一个类实现quartz提供的Job接口
(2)实现Job接口定义的execute方法,定义任务逻辑

代码如下(示例):

public class MyJob implements Job {private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");public void execute(JobExecutionContext jobExecutionContext)throws JobExecutionException {//执行任务的逻辑String time = sdf.format(new Date());System.out.println("~~~~~"+time);}
}

3.启动任务

使用任务调度器Scheduler进行任务管理

  • 启动任务
  • 暂停任务
  • 继续任务
  • 停止任务
package com.qfedu.job;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
public class QuartzTest {public static void main(String[] args) {try {//1.创建Quartz的任务调度器Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();//2.创建触发器:定义了任务调度的时机(延时、循环、定时...)// simpleScheduleBuilder对象表示任务的触发规则SimpleScheduleBuilder simpleScheduleBuilder =SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).withRepeatCount(10);SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")// withIdentity 设置trigger唯一表示.startAt(new Date(System.currentTimeMillis() + 5000))// startAt 设置首次触发时间.withSchedule(simpleScheduleBuilder)// withSchedule 设置触发器的触发规则.build(); // 通过TriggerBuilder对象,构造Trigger对象//3.创建任务(JobDetail 用于封装具体的任务)JobDetail job = JobBuilder.newJob(MyJob.class).build();//将任务及触发器,绑定到任务调度scheduler.scheduleJob(job,trigger);//启动任务scheduler.start()} catch (SchedulerException e) {e.printStackTrace();}}
}

三、基本实现原理

  • scheduler:任务调度器(执行调度的控制器)
  • trigger:触发器,用于定义任务调度时间规则
  • job:任务,即被调度的任务
    在这里插入图片描述

1. Scheduler任务调度器

Scheduler任务调度器由SchedulerFactory 工厂创建,主要提供了以下两种工厂实现:

  • DirectSchedulerFactory(使用较麻烦,需要进行编码配置)
  • StdSchedulerFactory(✔)

Scheduler 主要有三种:

  • RemoteMBeanScheduler
  • RemoteScheduler
  • StdScheduler(✔)
    创建任务调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

2. Triggers触发器

用于定义调度时间的元素,例如按照什么时间规则去执行任务
主要包括四种类型(这里只详细介绍SimpleTrigger和CronTrigger)

  • DateIntervalTrigger 日期周期的规则的触发器
  • NthIncludedDayTrigger 排除指定时间周期和日期的触发器

2.1 SimpleTrigger

使用简单便捷。可以满足的调度需求是:在具体的时间点执行一次,或者在具体的时间点执行并且以制定的间隔重复执行若干次。
适用场景:

  1. 延时任务:当用户提交订单之后启动任务,延时30min检查订单状态,如果未支付则取消订单
    释放库存
  2. 循环任务:每个指定的时间周期执行一次任务,任务可以循环(可以无限循环、可以循环指
    定的次数、还可以循环执行到指定的时间点)
  3. 定时任务:在指定的时间点调度执行任务
    规则:
  4. 重复次数,可以是0、正整数,以及常量SimpleTrigger.REPEAT_INDEFINITELY
  5. 重复的间隔,必须是0,或者long型的正数,表示毫秒。注意,如果重复间隔为0,trigger将会以重
    复次数并发执行(或者以scheduler可以处理的近似并发数)。
  6. endTime属性的值会覆盖设置重复次数的属性值;比如,你可以创建一个trigger,在终止时间之前
    每隔10秒执行一次,你不需要去计算在开始时间和终止时间之间的重复次数,只需要设置终止时间
    并将重复次数设置为REPEAT_INDEFINITELY。
//指定时间触发,每隔10秒执行一次,重复10次:
SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10);
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity("trigger3", "group1").startAt(myTimeToStartFiring) //指定触发的时间.withSchedule(simpleScheduleBuilder) //指定触发器的时间规则.forJob(myJob).build();

2.2 CronTirgger

使用cron表达式定义触发任务的时间规则,通常比SimpleTrigger更有用,如果需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。使用CronTrigger可以指时间表,例如“每周五中午”或“每个工作日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。

// 通过cron表达式定义触发任务的时间规则
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/3 * * * * ?");
//触发器
CronTrigger cronTrigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity("cronTrigger1","group1").startAt( DateBuilder.futureDate(5, DateBuilder.IntervalUnit.SECOND) )//设置首次执行任务的时间.withSchedule( cronScheduleBuilder ) //将时间规则设置给触发器.endAt(DateBuilder.dateOf(22,0,0) ) //设置任务终止的时间.build();

简单介绍一下Cron表达式:
由七个子表达式组成的字符串(最后一个年份可省略)

Seconds Minutes Hours Day-of-Month Month Day-of-Week Year秒      分    时        日期      月份    星期几   年份
//示例
#每5分钟就会触发一次
“0 0/5 * * *?”
#每5分钟触发一次,分钟后10秒(即上午1010分,上午10:05:10等)。
“10 0/5 * * *?”

3. Misfire策略

Misfire当已经绑定到调度器Scheduler的触发器及任务在执行的过程中,因Scheduler出现故障停止了、或者线程池中没有充足的线程执行到期的任务,从而导致Trigger触发周期到了但是任务没有执行的情况。
对于所有类型的Trigger,Quartz都为其指定了默认的定义其恢复之后的执行策略——MISFIRE_INSTRUCTION_SMART_POLICY(立即执行misfire的任务,然后继续按计划往后执行)

  1. SimpleTrigger的Misfire策略
#当资源可用时立即执行所有misfire的任务,执行到设置的endTime剩余的周期次数
MISFIRE_INSTRUCTION_FIRE_NOW
#不会判断misfire,当资源可用时立即执行所有misfire的任务,然后按照原计划执行
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
#立即执行第一次misfire任务,修改startTime为当前时间,按照原来的时间间隔执行下一次任务(总次数不变)
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT
# 立即执行第一次misfire任务,修改startTime为当前时间,按照原来的时间间隔执行下一次任务(剩下的任务)
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
# 不会立即执行任务,等到下一次计划时间到达时开始执行,忽略已经发生的misfire任务
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT
# 不会立即执行任务,等到下一次计划时间到达时开始执行,忽略已经发生的misfire任务
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT//示例
SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever()//.withMisfireHandlingInstructionFireNow()//.withMisfireHandlingInstructionIgnoreMisfires()//.withMisfireHandlingInstructionNextWithExistingCount()//.withMisfireHandlingInstructionNextWithRemainingCount()//.withMisfireHandlingInstructionNowWithExistingCount().withMisfireHandlingInstructionNowWithRemainingCount();
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").withSchedule(simpleScheduleBuilder) .build();
  1. CronTrigger的Misfire策略
# 立即执行所有的misfire任务,然后继续按计划执行
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
# 发生的misfire的任务都会被忽略,从当前时间按照原计划执行
MISFIRE_INSTRUCTION_DO_NOTHING
#立即执行第一个发生misfire的任务,忽略其他misfire的任务,然后按照原计划继续执行
MISFIRE_INSTRUCTION_FIRE_ONCE_NOW //示例
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 12 ? * MON#1 2022")//.withMisfireHandlingInstructionIgnoreMisfires()//.withMisfireHandlingInstructionDoNothing().withMisfireHandlingInstructionFireAndProceed();
CronTrigger cronTrigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity("cronTrigger1","group1").withSchedule( cronScheduleBuilder ).build();

4 任务Job

4.1 Job

Job表示被调度的任务,在任务调度的业务开发中,quartz提供了Job接口,我们自定义执行任务类实现此Job接口,在execute方法中完成业务的执行。

  • 两种类型的Job:无状态的和有状态的
    有状态的job不能被并行执行,只有上一次触发的任务被执行完之后才能触发下一次执行。
  • 两种属性:volatility 和 durability
    其中 volatility 表示任务 是否被持久化 到数据库存储,而 durability 表示在没有 trigger 关联的时候任务是否被保留。两者都是在值为 true 的时候任务被持久化或保留。

4.2 JobDetail

用于封装Job实例所包含的属性

//创建任务(JobDetail 用于封装具体的任务)
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1","group1") //设置任务的标识.build();

4.3 JobDataMap

包含不限量的(序列化的)数据对象,在job实例执行的时候,可以使用其中的数据。

//将job加入到scheduler之前,在构建Trigger、JobDetail时,可以将数据放入JobDataMap
//1.创建Quartz的任务调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//2.创建触发器
SimpleScheduleBuilder simpleScheduleBuilder =SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).withRepeatCount(10).withMisfireHandlingInstructionNextWithRemainingCount();
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(simpleScheduleBuilder).usingJobData("key1","value1") //设置Trigger参数.build();
//3.创建任务(JobDetail 用于封装具体的任务)
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1","group1").usingJobData("key2","value2") //设置JobDetail参数.build();
scheduler.scheduleJob(job,trigger);
scheduler.start();
//在Job执行过程中,可以从JobDataMap中取出数据
public class MyJob implements Job {private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");public void execute(JobExecutionContext jobExecutionContext)throws JobExecutionException {//执行任务的逻辑// 通过execute方法的JobExecutionContext参数获取触发器、JobDetail绑定的参数// 1.获取trigger中传递的参数JobDataMap jobDataMap1 = jobExecutionContext.getTrigger().getJobDataMap();String value1 = (String) jobDataMap1.get("key1");// 2.获取JobDetail中传递的参数JobDataMap jobDataMap2 =jobExecutionContext.getJobDetail().getJobDataMap();String value2 = (String) jobDataMap2.get("key2");String time = sdf.format(new Date());System.out.println("~~~~~"+time+"\t"+value1+"\t"+value2);}
}

学习地址:
java涛哥:Quartz任务调度框架

这篇关于Quartz任务调度框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130072

相关文章

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

Spring Framework系统框架

序号表示的是学习顺序 IoC(控制反转)/DI(依赖注入): ioc:思想上是控制反转,spring提供了一个容器,称为IOC容器,用它来充当IOC思想中的外部。 我的理解就是spring把这些对象集中管理,放在容器中,这个容器就叫Ioc这些对象统称为Bean 用对象的时候不用new,直接外部提供(bean) 当外部的对象有关系的时候,IOC给它俩绑好(DI) DI和IO

Sentinel 高可用流量管理框架

Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 Sentinel 具有以下特性: 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应

利用Django框架快速构建Web应用:从零到上线

随着互联网的发展,Web应用的需求日益增长,而Django作为一个高级的Python Web框架,以其强大的功能和灵活的架构,成为了众多开发者的选择。本文将指导你如何从零开始使用Django框架构建一个简单的Web应用,并将其部署到线上,让世界看到你的作品。 Django简介 Django是由Adrian Holovaty和Simon Willison于2005年开发的一个开源框架,旨在简

Yii框架relations的使用

通过在 relations() 中声明这些相关对象,我们就可以利用强大的 Relational ActiveRecord (RAR) 功能来访问资讯的相关对象,例如它的作者和评论。不需要自己写复杂的 SQL JOIN 语句。 前提条件 在组织数据库时,需要使用主键与外键约束才能使用ActiveReocrd的关系操作; 场景 申明关系 两张表之间的关系无非三种:一对多;一对一;多对多; 在

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl