• Quartz定时任务基础学习


    Quartz基础笔记

    前言

    1、什么是Quartz

    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目

    2、Quartz的运行环境是什么?

    • Quartz可以运行嵌入在一个独立式应用程序
    • Quartz可以在应用服务器或者Servlet容器实例化,并且参与事务
    • Quartz可以作为一个独立的程序运行在自己的Java虚拟架构中,可以通过RMI使用
    • Quartz可以被实例化,作为独立的项目集群(负载均衡或者故障转移功能),用于作业的执行

    3、Quartz的运行环境

    • Builder模式
    • Factory模式
    • 组件模式
    • 链式编程

    一、Quartz的核心概念

    学习Quartz之前我们需要了解几个概念:

    1. Job(任务)

    我们可以把这里Job理解为一个进程下的多个线程,Job表示一个工作,也就是执行具体业务逻辑的一个类,它里面就一个方法execuate

    void execute(JobExecutionContext context) 
    
    • 1
    1. JobDeatil(可执行的任务调度)

    这里的JobDetail我么可以看作是一个封装的Job类,只有将具体的业务Job封装成JobDetail才可以被Quartz识别并调用。另外 JobDetail 还包含了这个任务调度的方案和策略。

    1. Trigger(触发器)

    代表一个调度参数的配置,即我们时候去调用在Trigger里设置

    1. Scheduler(调度容器)

    是一个整合JobDetail和Trigger的容器,一个Scheduler里可以放置多个JobDetail和Trigger

    在这里插入图片描述

    1.1 案例DEMO

    由上图我们可以清楚的了解到,一个jobDetail是由JobBuilder创建,一个Trigger是由TriggerBuilder创建。而JobDetail和Trigger里可以创建对应的JobDataMap,往Map里加一些参数,供execuate方法里获取到对应的JobDataMap根据键获取到对应的属性值。

    【引入依赖】

    <dependencies>
    		
    		<dependency>
    			<groupId>org.quartz-schedulergroupId>
    			<artifactId>quartzartifactId>
    			<version>2.3.2version>
    		dependency>
    
    		
    		<dependency>
    			<groupId>org.quartz-schedulergroupId>
    			<artifactId>quartz-jobsartifactId>
    			<version>2.3.2version>
    		dependency>
    		
    		
    		<dependency>
    			<groupId>org.slf4jgroupId>
    			<artifactId>slf4j-log4j12artifactId>
    			<version>1.7.12version>
    		dependency>
    		<dependency>
    			<groupId>log4jgroupId>
    			<artifactId>log4jartifactId>
    			<version>1.2.17version>
    		dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    【分析步骤】

    1. 由stdSchedulerFactory创建一个Scheduler
    // 创建一个scheduler
    Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    
    • 1
    • 2

    可以通过scheduler获取到context(这里的context就是execuate里面的参数JobExecutionContext context),从而往里面设置一些属性

    1. 由scheduler创建对应的JobDetail和Trigger
    // 创建JobDetail 由JobBuilder创建
    		JobDetail job = JobBuilder.newJob(MyJob.class)
    									.withIdentity("myjob", "mygroup")
    									.usingJobData("j1", "jv1")
    									.build();
    		job.getJobDataMap().put("j2", "jv2");
    		
    		// 创建Trigger 由TriggerBuilder创建
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "group1")
                    .usingJobData("t1", "tv1")
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3)
                            .repeatForever()).build();
            trigger.getJobDataMap().put("t2", "tv2");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    由scheduler创建的JobDetail和Trigger都支持链式编程,而且创建出来的JobDetail和Trigger都必须要添加一个属性withIdentity(String key,String value)

    1. 由scheduler添加创建出来的JobDetail和Trigger
    scheduler.scheduleJob(JobDetail,Trigger);
    
    • 1
    1. 启动Scheduler
    scheduler.start();
    
    • 1

    在这里插入图片描述

    如上图所示,Trigger每隔2s调用一次JobDetail执行Job所实现的Job真正的业务

    上述示例是一个SimpleScheduler调度的。

    1.2 Quartz核心API

    Scheduler:与调度程序交互的接口

    Job:你想要调度器执行的任务的组件所实现的接口

    JobDetail:用于定义任务作业的示例

    Trigger:触发器,用于定时调用JobDetail所封装的Job的组件

    JobBuilder:构建JobDetail的示例的

    TriggerBuilder:用于构建Trigger的示例的

    1.3 Job和obDetail介绍

    • Job:工作任务调度的接口,任务类需要实现该接口,该接口中定义execuate方法,类似JDK的TimeTask类的run方法,在里面编写执行业务逻辑。
    • Job实例在Quartz中的生命周期,每次调度器执行完毕,他在调用execuate方法之前都会先创建一个新的Job实例,把原来的释放,释放的实力会被垃圾回收机制收回。
    • JobDetail:jobDetail实力提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定的Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
    • jobDetail重要属性:name,group,jobClass,jobDataMap

    1.4 JobExecuateContext介绍

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

    1.5 JobDataMap介绍

    (1)使用Map获取

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

    1.6 有状态的Job和无状态的Job

    通过@PersistJobDataAfterExecuation注解使用

    有状态的Job可以理解为多次Job调用期间可以持有一些信息,这些状态信息存储在JobDetail里面,而默认的无状态的Job每次调用都会创建一个新的JobDataMap。

    1.7 Trigger的详解

    和Job一样,Trigger也和Trigger一样很好使用,但是Trigger有很多的类型,这里只详细学习一下SimpleTriggerCornTrigger两个核心的Trigger类型

    1.7.1 Trigger的公共属性

    注意:不管什么类型的Trgger,都有一个必须的属性:TriggerKey,用于唯一标识一个Trigger

    除了TriggerKey以外,trigger还有一些公共属性。

    1. jobKey:当Trigger被触发的时候,执行的是哪一个Job
    2. startTime:开始触发的时间,该属性的值是一个java.util.Date类型的
    3. endTime:Trigger失效的时间点,比如说一个每个月的第五天执行的Trigger,假如他的endTime设置成7月1日,那么他最后一次执行的时间就是6月5日

    1.7.2 Trigger的公共属性🔥🔥

    SimpleTrigger可以满足的调度需求是:在具体的时间点执行一次,或者在具体的时间点执行,并且以指定的间隔重复执行若干次。比如,你有一个trigger,你可以设置它在2015年1月13日的上午11:23:54准时触发,或者在这个时间点触发,并且每隔2秒触发一次,一共重复5次。


    SimpleTrigger的属性包括:开始时间、结束时间、重复次数以及重复的间隔。

    1. 开始时间:
    2. 结束时间
    3. 重复次数:可以是0、正整数,以及常量SimpleTrigger.REPEAT_INDEFINITELY
    4. 重复的间隔:必须是0,正整数
    public class MainHelloTrigger {
    
    	public static void main(String[] args) throws Exception {
    		// 任务调度器 StdSchedulerFactory
    		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    		// 设置任务的开始时间
    		Date startDate = new Date();
    		// 延迟3s执行
    		startDate.setTime(startDate.getTime()+3000);
    		// 设置任务的结束时间
    		Date endDate = new Date();
    		endDate.setTime(endDate.getTime()+10000);
    		// 调度任务实例
    		JobDetail jobDetail = JobBuilder.newJob(HelloJobTrigger.class) 		// 加载任务类的实例
    				.withIdentity("helloJob", "HelloJobGroup")			// 参数一:任务的名称(唯一实例);参数二:任务组的名称
    				.build();
    		
    		// 触发器Trigger
    		Trigger trigger = TriggerBuilder.newTrigger() 				// 创建一个触发器
    				.withIdentity("HelloTrigger", "HelloTiggerGroup") 	// 参数一:触发器的名称;参数二:触发器的群组名
    //				.startNow() // 马上启动触发器 只执行一次
    //				.startAt(startDate) // 设置任务的开始时间
    				.endAt(endDate)				.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) // 创建一个每5s重复执行一次的简单调度器 
    				.build();
    	
    		// 获取触发器的名称以及组的名称 同理Job  如果不指定组名,按默认去执行  任务/触发器的名称必须要指明
    		
    		// 让调度器Scheduler关联触发器和任务
    		scheduler.scheduleJob(jobDetail,trigger);
    		// 启动scheduler调度任务
    		scheduler.start();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    1.8 CronTrigger

    CronTrigger通常比Simple Trigger更有用,如果您需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。

    使用CronTrigger,您可以指定号时间表,例如“每周五中午”或“每个工作日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。

    即使如此,和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。

    二、Quartz配置

    2.1配置、资源SchedularFactory

    Quartz以模块方式架构,因此,要是他运行,几个组件必须很好二点聚合在一起,幸运的是,已经有了一些现存的助手可以完成这些工作。

    所有的Schedular实例都是由SchedularFactory创建。

    Quartz的三个核心概念,调度器,任务,触发器。三者之间的关系是:

    在这里插入图片描述

    大家都知道,一个作业,比较重要的三个参数就是Scheduler,jobDetail,Trigger;而Trigger对于JOB而言就是好比一个驱动器;没有触发器来定时驱动作业,作业就无法运行;对于JobDetail而言,一个Job可以对应多个Trigger

    创建Scheduler的方式有两种:

    方式一:

    Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    
    • 1

    方式二:

    SchedulerFactory factory = new StdSchedulerFactory();
    Scheduler scheduler = factory.getScheduler();
    
    • 1
    • 2

    2.2、Quartz.properties

    默认路径:quartz.2.3.0中的org.quartz中的quartz.properties

    在这里插入图片描述

    组成部分:

    • 调度器属性

    org.quartz.scheduler.instanceName:属性用来区分特定的调度器实例,可以按照功能用途来给调度器起名。

    org.quartz.scheduler.instanceId:属性和前者一样,允许任何字符串,但是这个值必须要在所有的调度器实例中是唯一的,尤其是在一个集群的环境中。作为唯一的key。

    • 线程池属性

    threadCount

    处理Job的线程数目,至少为1,但是最多的话最好不要超过100,再多台机器上设置值超过100的话,会显得相当不适用。特别是在Job执行时间较长的情况下。

    • threadPriority

    现成的优先级,优先级高的线程优先得到执行。最小的1;其次最大的是10。默认是5

  • 相关阅读:
    Python蓝桥杯---2的次幂表示
    Unity Mirror学习(一) SyncVars属性使用
    LG P3990 【SHOI2013】 超级跳马 解题报告
    Python+ Flask轻松实现Mock Server
    Linux下udev应用
    基础:types of keys
    阿里云短信服务接入流程
    基于Or-Tools的整数规划问题求解
    SpringBoot整合XXL-JOB详解
    linux java 环境变量配置
  • 原文地址:https://blog.csdn.net/mmklo/article/details/127707725