Quartz处理定时任务的核心概念

合集下载

quartz 实现job类 的 execute 方法-概述说明以及解释

quartz 实现job类 的 execute 方法-概述说明以及解释

quartz 实现job类的execute 方法-概述说明以及解释1.引言1.1 概述在使用Quartz框架开发定时任务时,我们经常需要实现一个Job类,并在其中编写具体的任务逻辑。

而Job类的核心方法就是execute方法,它定义了当定时任务被触发时所执行的逻辑。

因此,正确实现execute方法是保证定时任务准确执行的关键。

在本文中,我们将深入探讨Quartz框架中Job接口以及execute方法的作用和实现方式。

我们将介绍Quartz框架的基本概念,Job接口的作用,以及如何正确地实现Job类的execute方法。

通过本文的学习,读者将能够深入理解Quartz框架的核心机制,并能够准确地编写定时任务的业务逻辑。

1.2 文章结构本文将分为引言、正文和结论三个部分。

在引言部分,将对文章的概述、结构和目的进行介绍,为读者提供整体的阅读指引。

在正文部分,将首先简要介绍Quartz框架的基本概念和特点,然后重点讨论Job接口及其核心方法execute方法的作用和实现方式。

最后,将详细探讨如何实现一个含有execute方法的Job类,并通过示例代码进行说明。

在结论部分,将总结实现execute方法的重要性,提供进一步学习和实践的建议,并结束全文的讨论。

整体结构清晰,内容丰富,旨在帮助读者深入理解Quartz 框架中的Job执行机制。

1.3 目的本文的主要目的是探讨如何实现Quartz框架中Job类的execute方法。

通过深入研究Quartz框架的Job接口以及execute方法的功能和作用,我们将能够更好地理解定时任务调度的机制和原理。

此外,通过具体的示例和实践操作,我们将向读者展示如何实现一个自定义的Job类,并编写其execute方法,从而实现定时任务的具体业务逻辑。

通过本文的学习,读者将能够掌握Quartz框架的基本原理和用法,了解Job类的重要性以及execute方法的作用。

同时,通过实际操作和实现的过程,读者将能够提升自己的编程技能和对定时任务调度的理解,为今后在实际项目中应用Quartz框架提供有力支持。

quartz实现原理

quartz实现原理

Quartz是一款强大的开源作业调度库,它实现了定时任务的调度和管理。

Quartz的原理主要基于以下几个核心概念:1. 作业(Schedule):作业是Quartz中的基本单位,它代表了一个需要执行的任务。

作业由一个唯一标识符和一组触发器(Trigger)组成。

作业可以设置多个触发器,从而可以被多次触发执行。

2. 触发器(Trigger):触发器定义了作业的执行规则,包括作业的执行时间、频率等。

Quartz 提供了多种类型的触发器,如简单触发器(SimpleTrigger)和Cron 表达式触发器(CronTrigger)。

3. 执行器(Executor):执行器负责作业的执行。

Quartz内置了多种执行器,如单线程执行器(SingletonExecutor)和多线程执行器(ThreadPoolExecutor)。

执行器可以根据实际需求进行扩展,自定义执行器可以实现对作业执行的控制,如限制并发执行等。

4. 存储器_Store):Quartz将作业、触发器和执行器的信息存储在某种数据存储系统中,如关系数据库、内存等。

存储器负责存储这些信息,并在需要时提供给Quartz使用。

5. 调度器(Scheduler):调度器是Quartz的核心组件,它负责解析触发器、创建作业实例、绑定触发器到作业实例以及触发作业执行等。

调度器在启动时初始化,它会读取存储器中的数据,并根据触发器的规则创建作业实例,然后将触发器与作业实例绑定。

当触发器满足条件时,调度器会触发作业执行。

Quartz的工作流程如下:1. 配置Quartz:首先,需要配置Quartz的调度器、存储器、执行器等。

这可以通过编程方式或配置文件进行配置。

2. 创建作业和触发器:使用Quartz提供的API创建作业和触发器。

作业可以设置多个触发器,从而可以被多次触发执行。

3. 调度器初始化:在应用程序启动时,初始化调度器。

调度器会读取存储器中的数据,并根据触发器的规则创建作业实例,然后将触发器与作业实例绑定。

原创Quartz定时任务学习

原创Quartz定时任务学习

原创Quartz定时任务学习(一)简单任务学习quartz首先了解三个概念:调度器:负责调度作业和触发器;触发器:设置作业执行的时间、参数、条件等;(简单触发器和Cron触发器)作业:定时任务内容,被执行的程序;下载必要的jar包,将quartz-x.x.x.jar和core和/或optional文件夹中的jar文件放在项目的文件夹或项目的类路径中Quartz的几个核心的接口和类为:Job接口:自己写的"定时程序"实现此接口的voidexecute(JobExecutionContext arg0)方法,Job还有一类为有状态的StatefulJob接口,如果我们需要在上一个作业执行完后,根据其执行结果再进行下次作业的执行,则需要实现此接口。

Trigger抽象类:调度类(Scheduler)在时间到时调用此类,再由trigger 类调用指定的定时程序。

Quertz中提供了两类触发器为:SimpleTrigger,CronTrigger。

前者用于实现比较简单的定时功能,例如几点开始,几点结束,隔多长时间执行,共执行多少次等,后者提供了使用表达式来描述定时功能,因此适用于比较复杂的定时描述,例如每个月的最后一个周五,每周的周四等。

JobDetail类:具体某个定时程序的详细描述,包括Name,Group,JobDataMap等。

JobExecutionContext类:定时程序执行的run-time的上下文环境,用于得到当前执行的Job的名字,配置的参数等。

JobDataMap类:用于描述一个作业的参数,参数可以为任何基本类型例如String,float等,也可为某个对象的引用.JobListener,TriggerListener接口:用于监听触发器状态和作业扫行状态,在特写状态执行相应操作。

JobStore类:在哪里执行定进程序,可选的有在内存中,在数据库中。

开始:边看例题边学习,首先从简单触发器开始…1、作业通过实现org.quartz.job接口,可以使Java类变成可执行的。

quartz执行原理

quartz执行原理

quartz执行原理
Quartz是一个开源的任务调度系统,其执行原理如下:
1. Quartz通过Job和Trigger两个核心概念来完成任务调度。

Job 表示一个需要执行的任务,Trigger用于触发Job执行。

2. Quartz的任务调度是基于时间的,即指定了任务执行的时间,Quartz会根据时间触发Trigger来执行Job。

3. Quartz的任务调度过程是由Scheduler控制的。

Scheduler负责调度所有Job和Trigger,根据Trigger的设置来触发Job的执行。

4. 当一个Job被Scheduler触发执行时,Quartz会创建一个新的Job实例,并调用其execute方法来执行任务。

5. Job的execute方法是在一个独立的线程中执行的,执行结果和任务执行时间都会被记录在Quartz的数据库中,以便于后续的查询和分析。

6. 当一个Trigger的时间到了,Scheduler会重新计算下一次的执行时间,并将其存储在数据库中,以便于下次触发。

如果Trigger被暂停或者停止,则下一次执行时间会被相应的更新或者取消。

7. 除了时间驱动的触发方式,Quartz还支持多种事件驱动的触发方式,例如JMS消息、HTTP请求等,以满足不同的任务调度需求。

总之,Quartz的任务调度是非常灵活和可靠的,通过它可以方便地实现任务调度和管理,提高系统的稳定性和效率。

Java定时任务框架详细分析

Java定时任务框架详细分析

Java定时任务框架详细分析定时任务是开发中常见的需求之一,用于在指定的时间间隔内执行特定的任务。

为了方便管理和调度,Java开发社区提供了许多成熟的定时任务框架。

本文将详细分析几个主流的Java定时任务框架,包括Quartz、Spring Task和Elastic-Job。

一、Quartz定时任务框架Quartz是Java中最受欢迎的定时任务框架之一。

它提供了丰富的功能和灵活的配置选项,非常适合各种任务调度需求。

下面将对Quartz框架的核心概念和用法进行分析。

1.1 Job和Trigger在Quartz中,任务通过Job来表示,可以通过实现Job接口或继承Quartz提供的Job类来定义具体的任务逻辑。

Trigger用来触发任务的执行,可以设置任务的执行时间、频率和条件等。

1.2 调度器和调度器工厂Quartz的调度器(Scheduler)负责管理和执行任务,通过调度器工厂(SchedulerFactory)来创建和初始化调度器。

调度器可以配置多个触发器,每个触发器关联一个任务。

1.3 Quartz的核心功能Quartz提供了许多核心功能,包括任务持久化、错过任务处理、任务监听器、集群支持等。

任务持久化允许将任务信息存储在数据库中,可以在应用重启后继续执行未完成的任务。

错过任务处理则确保任务不会因为系统故障或应用不可用而丢失。

任务监听器可以监控任务的执行情况,并在任务状态发生变化时执行相应的操作。

集群支持则可以实现任务的负载均衡和高可用性。

二、Spring Task定时任务框架Spring Task是基于Spring框架的一个轻量级定时任务框架,它与Spring无缝集成,使用简单方便。

下面将对Spring Task框架的核心特性进行详细分析。

2.1 使用注解定义任务Spring Task允许使用注解方式定义定时任务,通过在方法上添加@Scheduled注解,可以指定任务的执行时间和频率。

任务方法可以是任意public方法,无需实现特定接口,方便灵活。

quartz用法

quartz用法

Quartz用法一、什么是Quartz?Quartz是一个功能强大且广泛应用于Java中的开源任务调度框架。

它允许开发人员通过简单而灵活的方式在应用程序中调度和执行任务。

无论是简单的定时任务还是复杂的作业调度,Quartz都可以满足需求。

二、Quartz的基本概念在深入探讨Quartz的用法之前,我们首先需要了解一些基本概念。

1. 作业(Job)作业是Quartz中最基本的调度单元。

它表示一项任务或一个操作,可以被Quartz 调度和执行。

2. 触发器(Trigger)触发器是Quartz中用于指定作业何时执行的组件。

可以根据时间表达式(如每小时、每天等)来触发作业的执行,也可以根据特定的日期和时间来触发。

3. 调度器(Scheduler)调度器是Quartz的核心组件,它负责在指定的时间触发作业的执行。

调度器可以同时管理多个作业和触发器,并根据设定的调度策略来决定执行顺序。

三、Quartz的用法接下来,我们将深入探讨Quartz的用法,包括作业和触发器的创建、调度器的配置和管理。

1. 创建作业要创建一个作业,我们需要定义一个类,实现Quartz的Job接口,并重写其中的execute()方法。

在execute()方法中,我们可以编写具体的任务逻辑。

例如:public class MyJob implements Job {public void execute(JobExecutionContext context) throws JobExecutionExcept ion {// 编写具体的任务逻辑}}2. 创建触发器Quartz提供了多种触发器类型,可以根据需求灵活选择。

其中最常用的是SimpleTrigger和CronTrigger。

•SimpleTrigger:简单触发器会在指定的时间间隔内循环执行作业。

可以设置作业的开始时间、结束时间和重复次数。

•CronTrigger:基于Cron表达式触发器允许我们非常灵活地指定作业的执行时间。

quartz

quartz

主要概念介绍和吐槽是一个开源任务调度框架,它通过轮询和定时器等方式来执行定时任务,同时提供了多种方式来定义任务的时间间隔和执行次数。

主要有以下几个概念:1. 任务(Job):表示一个要执行的具体任务,通常需要继承抽象类IJob并实现其Execute方法。

2. 任务调度器(Scheduler):是任务调度框架的核心,负责任务的调度和执行,它可以在运行时动态添加、删除和修改任务以及调整各个任务的执行时间。

同时,它也可以注入依赖项、注册监听器等。

3. 触发器(Trigger):用于控制任务的执行时间和频率,是任务调度器的重要组成部分,可以基于时间、日期、间隔等规则来定义任务的执行时间。

4. 触发器器工厂(TriggerFactory):用于创建触发器实例,它提供了几种常用的触发器类型,包括简单触发器(SimpleTrigger)、Cron触发器(CronTrigger)、日历触发器(CalendarIntervalTrigger)等。

5. 作业存储(JobStore):是任务调度器的核心组件之一,通常用于存储和管理作业/触发器的配置信息、状态信息、历史记录等信息,支持各种类型的数据存储方式。

的主要优点是易于使用和扩展,支持分布式任务调度,可靠性和稳定性较高。

但是,也存在一些缺点和不足,例如:1. 缺乏良好的文档和示例:尽管的社区比较活跃,但是其文档和示例相对较少,对新手来说较为困难。

2. 限制较多的集群管理:虽然支持分布式任务调度,但是其集群管理功能相对较弱,不太适合大规模的分布式任务调度。

3. 性能较低:在处理大量并发任务和高负载时,性能表现较低。

总之,是一个比较成熟、稳定的任务调度框架,其优点是易于使用和扩展,但是在性能、文档等方面还有一定的提升空间。

鉴于受欢迎的程度及其实际使用场景并没有和其他框架有很大的区别,因此学习相关知识可以看看官方文档,并结合相关案例进行实践,同时也可以到相关社区论坛发帖咨询。

quartz工作原理

quartz工作原理

Quartz是一个大名鼎鼎的Java版开源定时调度器,功能强悍,使用方便。

一、核心概念Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可。

1、Job表示一个工作,要执行的具体内容。

此接口中只有一个方法void execute(JobExecutionContext context)2、JobDetailJobDetail表示一个具体的可执行的调度程序,Job是这个可执行程调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。

3、Trigger代表一个调度参数的配置,什么时候去调。

4、Scheduler代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger。

当Trigger 与JobDetail组合,就可以被Scheduler容器调度了。

二、一个最简单入门实例执行结果:当把结束时间改为://设置重复停止时间,并销毁该Trigger对象java.util.Calendar c = java.util.Calendar.getInstance();c.setTimeInMillis(System.currentTimeMillis() + 1000 * 1L);strigger.setEndTime(c.getTime());执行结果:当添加一条关闭调度器的语句://4、并执行启动、关闭等操作scheduler.start();scheduler.shutdown(true);程序执行结果:Thu Jul 23 10:11:50 CST 2009: doing something...Process finished with exit code 0仅仅执行了一次,这一次能执行完,原因是设定了scheduler.shutdown(true);true表示等待本次任务执行完成后停止。

从这里也可以看出,scheduler是个容器,scheduler控制jobDetail的执行,控制的策略是通过trigger。

定时调度之Quartz.Net(一)

定时调度之Quartz.Net(一)

定时调度之(⼀)⼯作中我们经常碰到定时或者固定时间点去做⼀些事情,然后每天到时间点就会去做这样的事情,如果理解这样的场景,我们就要引⼊今天我们的主⾓Quartz,其实这个跟数据库的作业类似,但是不仅仅局限于数据库。

⼀: quartZ引⼊&三⼤核⼼对象简介1:在项⽬中打开Nuget管理,然后搜索QuartZ,现在最新的版本是3.0.7,需要在Framework4.5.2上⾯使⽤。

2:quartZ的三⼤核⼼对象A:IScheduler:单元/实例,在这⾥去完成定时任务的配置,只有单元启动,⾥⾯的作业才能正常运⾏B:IJob:任务,定时执⾏动作就是JobC:ITrigger:定时策略(设置执⾏的频率或者执⾏⽅式)⼆:三⼤核⼼对象的初始化以及使⽤如下:#region schedulerConsole.WriteLine("初始化scheduler......");StdSchedulerFactory factory = new StdSchedulerFactory();IScheduler scheduler = await factory.GetScheduler();//scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener());//scheduler.ListenerManager.AddTriggerListener(new CustomTriggerListener());//scheduler.ListenerManager.AddJobListener(new CustomJobListener());await scheduler.Start();#endregion//IJob ITrigger{//创建作业IJobDetail jobDetail = JobBuilder.Create<TestJob>().WithIdentity("testjob", "group1").WithDescription("This is TestJob").Build();//IJobDetail jobDetail = JobBuilder.Create<TestStatefulJob>()// .WithIdentity("testjob", "group1")// .WithDescription("This is TestJob")// .Build();jobDetail.JobDataMap.Add("student1", "Milor");jobDetail.JobDataMap.Add("student2", "⼼如迷醉");jobDetail.JobDataMap.Add("student3", "宇洋");jobDetail.JobDataMap.Add("Year", DateTime.Now.Year);//ITrigger trigger = TriggerBuilder.Create()// .WithIdentity("trigger1", "group1")// .StartNow()// .WithSimpleSchedule(x => x// .WithIntervalInSeconds(10)// .WithRepeatCount(10)// .RepeatForever())// .WithDescription("This is testjob's Trigger")// .Build();//创建时间策略ITrigger trigger = TriggerBuilder.Create().WithIdentity("testtrigger1", "group1").StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(10)))//.StartNow()//StartAt.WithCronSchedule("5/10 * * * * ?")//每隔⼀分钟//"10,20,30,40,50,0 * * * * ?".WithDescription("This is testjob's Trigger").Build();trigger.JobDataMap.Add("student4", "Ray");trigger.JobDataMap.Add("student5", "⼼欲⽆痕");trigger.JobDataMap.Add("student6", "风在飘动");trigger.JobDataMap.Add("Year", DateTime.Now.Year + 1);await scheduler.ScheduleJob(jobDetail, trigger);Console.WriteLine("scheduler作业添加完成......");}[PersistJobDataAfterExecution] //执⾏后可以保留执⾏结果[DisallowConcurrentExecution] // 让⼀个任务执⾏完毕以后才去执⾏下⼀个任务public class TestJob : IJob{public TestJob(){Console.WriteLine("This is TestJob的构造。

.net quartz定时任务原理

.net quartz定时任务原理

.net quartz定时任务原理一、引言定时任务在软件开发中扮演着重要的角色,它可以帮助开发者按照预定的时间间隔执行某些任务,如数据同步、日志记录、定期清理等。

Quartz是.NET平台下的一款流行的定时任务框架,它提供了简单易用的API,使得开发者能够轻松地创建和管理定时任务。

本文将深入探讨.NET Quartz定时任务原理,帮助开发者更好地理解和应用这种技术。

二、Quartz框架介绍Quartz是一个开源的.NET定时任务框架,它提供了简单易用的API,用于创建、调度和管理定时任务。

Quartz支持多种触发器(Trigger)和执行器(Job),可以根据不同的需求灵活地配置任务。

Quartz框架的核心组件包括调度器(Scheduler)、触发器(Trigger)和作业(Job)。

调度器负责管理任务的调度和执行,触发器描述了任务的执行时间和条件,作业则是需要执行的任务。

三、定时任务原理1. 任务定义:在Quartz中,开发者需要先定义任务(Job),包括任务的类名、方法名等信息。

任务的实现可以是一个类中的方法,也可以是一个单独的类。

2. 触发器配置:定时任务的执行时间是由触发器(Trigger)来控制的。

Quartz提供了多种类型的触发器,如CronTrigger、SimpleTrigger等,可以根据不同的需求选择合适的触发器类型。

在配置触发器时,需要指定任务开始执行的时间和周期性执行的条件。

3. 调度器调度:当触发器配置完成后,调度器(Scheduler)会按照指定的时间间隔和条件,自动调度任务的执行。

调度器会根据触发器的类型和时间参数,将任务分配给可用的执行器(Executor)来执行。

4. 执行器执行:执行器(Executor)是Quartz框架中负责实际执行任务的组件。

Quartz提供了默认的线程池执行器,也可以根据需求自定义执行器。

当任务被分配给执行器后,它会按照指定的逻辑来执行任务。

quartz由浅入深

quartz由浅入深

quartz由浅入深一、quartz核心概念先来看一张图:●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。

Job运行时的信息保存在JobDataMap实例中;●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。

因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。

●Trigger:是一个类,描述触发Job执行的时间触发规则。

主要有SimpleTrigger和CronTrigger这两个子类。

当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等;●Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。

一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。

假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要在Trigger触发机制的基础上使用Calendar进行定点排除。

quartz_定时器执行原理_概述说明以及概述

quartz_定时器执行原理_概述说明以及概述

quartz 定时器执行原理概述说明以及概述引言部分的内容如下:1.1 概述Quartz定时器是一个功能强大且灵活的任务调度框架,它可以以预定的时间间隔或特定时间点触发指定的任务。

它可以帮助开发人员在复杂的应用中实现各种调度需求,并提供了可靠和稳定的任务执行机制。

本文将重点介绍Quartz定时器的执行原理及相关使用方法。

1.2 文章结构本文将按照以下结构来介绍Quartz定时器的执行原理和使用方法。

首先,我们将对Quartz进行简要介绍,包括其作用和特点。

然后,我们会详细讲解Quartz 定时任务的调度机制,包括任务触发方式和执行规则等内容。

接着,我们会深入探讨Quartz定时器的实现原理,解析其内部工作机制并说明其设计思路。

此外,我们还会给出配置Quartz定时器、创建定时任务以及执行定时任务的具体步骤和注意事项。

最后,我们会对Quartz定时器进行优缺点分析,并总结文章内容以及对Quartz定时器执行原理做出概述说明。

1.3 目的本文旨在帮助读者更加全面深入地了解Quartz定时器的底层执行原理和使用方法,使其能够正确配置和管理定时任务,并充分发挥Quartz的优势。

同时,通过分析Quartz定时器的优缺点,读者可以更好地评估其适用性和局限性,从而在实际应用中做出明智的选择。

2. Quartz定时器执行原理2.1 Quartz简介Quartz是一个功能强大且广泛使用的Java定时任务调度框架。

它提供了灵活的任务调度方式,并支持多种触发器来定义任务执行的频率和时间规则。

2.2 定时任务的调度机制Quartz使用基于日历的调度机制来实现定时任务的执行。

它可以根据指定的时间触发器,在指定的时间点或者一定周期内执行任务。

Quartz支持各种类型的触发器,包括简单触发器、Cron触发器和日历触发器等。

- 简单触发器:它基于设定的间隔时间以及开始时间,按照预定规则重复执行任务。

- Cron触发器:它是基于Cron表达式定义任务执行规则,可以非常灵活地设置年、月、日、周、小时、分钟等参数。

一文揭秘定时任务调度框架quartz

一文揭秘定时任务调度框架quartz

⼀⽂揭秘定时任务调度框架quartz之前写过quartz或者引⽤过quartz的⼀些⽂章,有很多⼈给我发消息问quartz的相关问题,趁着年底⽐较清闲,把quartz的问题整理了⼀下,顺带翻了翻源码,做了⼀些总结,希望能帮助到⼀些⼈或者减少⼈们探索的时间。

注意,使⽤版本为quartz2.2.3 spring boot2.1.31.quartz的核⼼组件1.1 Job组件1.1.1JobJob负责任务执⾏的逻辑,所有逻辑在execute()⽅法中,执⾏所需要的数据存放在JobExecutionContext 中Job实例:@PersistJobDataAfterExecution@DisallowConcurrentExecutionpublic class ColorJob implements Job {private static Logger _log = LoggerFactory.getLogger(ColorJob.class);// parameter names specific to this jobpublic static final String FAVORITE_COLOR = "favorite color";public static final String EXECUTION_COUNT = "count";// Since Quartz will re-instantiate a class every time it// gets executed, members non-static member variables can// not be used to maintain state!private int _counter = 1;/*** <p>* Empty constructor for job initialization* </p>* <p>* Quartz requires a public empty constructor so that the* scheduler can instantiate the class whenever it needs.* </p>*/public ColorJob() {}/*** <p>* Called by the <code>{@link org.quartz.Scheduler}</code> when a* <code>{@link org.quartz.Trigger}</code> fires that is associated with* the <code>Job</code>.* </p>** @throws JobExecutionException* if there is an exception while executing the job.*/public void execute(JobExecutionContext context)throws JobExecutionException {// This job simply prints out its job name and the// date and time that it is runningJobKey jobKey = context.getJobDetail().getKey();// Grab and print passed parametersJobDataMap data = context.getJobDetail().getJobDataMap();String favoriteColor = data.getString(FAVORITE_COLOR);int count = data.getInt(EXECUTION_COUNT);_("ColorJob: " + jobKey + " executing at " + new Date() + "\n" +" favorite color is " + favoriteColor + "\n" +" execution count (from job map) is " + count + "\n" +" execution count (from job member variable) is " + _counter);// increment the count and store it back into the// job map so that job state can be properly maintainedcount++;data.put(EXECUTION_COUNT, count);// Increment the local member variable// This serves no real purpose since job state can not// be maintained via member variables!_counter++;}}1.1.2 JobDetail存储Job的信息主要负责1.指定执⾏的Job类,唯⼀标识(job名称和组别名称)2.存储JobDataMap信息// job1 will only run 5 times (at start time, plus 4 repeats), every 10 secondsJobDetail job1 = newJob(ColorJob.class).withIdentity("job1", "group1").build();// pass initialization parameters into the jobjob1.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "Green");job1.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);数据库存储如下:1.1.3 Quartz JobBuilder提供了⼀个链式api创建JobDetail@Beanpublic JobDetail jobDetail() {return JobBuilder.newJob().ofType(SampleJob.class).storeDurably().withIdentity("Qrtz_Job_Detail").withDescription("Invoke Sample Job service...").build();}1.1.4 Spring JobDetailFactoryBeanspring提供的⼀个创建JobDetail的⽅式⼯⼚bean@Beanpublic JobDetailFactoryBean jobDetail() {JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); jobDetailFactory.setJobClass(SampleJob.class);jobDetailFactory.setDescription("Invoke Sample Job service...");jobDetailFactory.setDurability(true);return jobDetailFactory;}1.2 Trigger组件trigger的状态不同trigger的状态// STATESString STATE_WAITING = "WAITING";String STATE_ACQUIRED = "ACQUIRED";String STATE_EXECUTING = "EXECUTING";String STATE_COMPLETE = "COMPLETE";String STATE_BLOCKED = "BLOCKED";String STATE_ERROR = "ERROR";String STATE_PAUSED = "PAUSED";String STATE_PAUSED_BLOCKED = "PAUSED_BLOCKED";String STATE_DELETED = "DELETED";状态的表结构trigger的类型// TRIGGER TYPES/** Simple Trigger type. */String TTYPE_SIMPLE = "SIMPLE";/** Cron Trigger type. */String TTYPE_CRON = "CRON";/** Calendar Interval Trigger type. */String TTYPE_CAL_INT = "CAL_INT";/** Daily Time Interval Trigger type. */String TTYPE_DAILY_TIME_INT = "DAILY_I";/** A general blob Trigger type. */String TTYPE_BLOB = "BLOB";对应表结构SimpleTrigger trigger1 = newTrigger().withIdentity("trigger1", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(4)).build();Trigger存储在mysql中1.2.2 Quartz TriggerBuilder提供了⼀个链式创建Trigger的api@Beanpublic Trigger trigger(JobDetail job) {return TriggerBuilder.newTrigger().forJob(job).withIdentity("Qrtz_Trigger").withDescription("Sample trigger").withSchedule(simpleSchedule().repeatForever().withIntervalInHours(1)).build();}1.2.3 Spring SimpleTriggerFactoryBeanspring提供的⼀个创建SimpleTrigger的⼯⼚类@Beanpublic SimpleTriggerFactoryBean trigger(JobDetail job) {SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean();trigger.setJobDetail(job);trigger.setRepeatInterval(3600000);trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);return trigger;}1.3 调度组件1.3.1 quartz提供的⼯⼚类@Beanpublic Scheduler scheduler(Trigger trigger, JobDetail job) {StdSchedulerFactory factory = new StdSchedulerFactory();factory.initialize(new ClassPathResource("quartz.properties").getInputStream());Scheduler scheduler = factory.getScheduler();scheduler.setJobFactory(springBeanJobFactory());scheduler.scheduleJob(job, trigger);scheduler.start();return scheduler;}1.3.2 spring提供的⼯⼚bean@Beanpublic SchedulerFactoryBean scheduler(Trigger trigger, JobDetail job) {SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();schedulerFactory.setConfigLocation(new ClassPathResource("quartz.properties"));schedulerFactory.setJobFactory(springBeanJobFactory());schedulerFactory.setJobDetails(job);schedulerFactory.setTriggers(trigger);return schedulerFactory;}2.⼯作原理2.1 核⼼类QuartzSchedulerScheduler实现类StdScheduler封装了核⼼⼯作类QuartzScheduler/*** <p>* Construct a <code>StdScheduler</code> instance to proxy the given* <code>QuartzScheduler</code> instance, and with the given <code>SchedulingContext</code>.* </p>*/public StdScheduler(QuartzScheduler sched) {this.sched = sched;}2.2 JobDetail的存取public void addJob(JobDetail jobDetail, boolean replace, boolean storeNonDurableWhileAwaitingScheduling) throws SchedulerException { validateState();if (!storeNonDurableWhileAwaitingScheduling && !jobDetail.isDurable()) {throw new SchedulerException("Jobs added with no trigger must be durable.");}resources.getJobStore().storeJob(jobDetail, replace);notifySchedulerThread(0L);notifySchedulerListenersJobAdded(jobDetail);}2.2.1 存储JobDetail信息(以mysql Jdbc⽅式为例)/*** <p>* Insert or update a job.* </p>*/protected void storeJob(Connection conn,JobDetail newJob, boolean replaceExisting)throws JobPersistenceException {boolean existingJob = jobExists(conn, newJob.getKey());try {if (existingJob) {if (!replaceExisting) {throw new ObjectAlreadyExistsException(newJob);}getDelegate().updateJobDetail(conn, newJob);} else {getDelegate().insertJobDetail(conn, newJob);}} catch (IOException e) {throw new JobPersistenceException("Couldn't store job: "+ e.getMessage(), e);} catch (SQLException e) {throw new JobPersistenceException("Couldn't store job: "+ e.getMessage(), e);}}调⽤StdJDBCDelegate实现/*** <p>* Insert the job detail record.* </p>** @param conn* the DB Connection* @param job* the job to insert* @return number of rows inserted* @throws IOException* if there were problems serializing the JobDataMap*/public int insertJobDetail(Connection conn, JobDetail job)throws IOException, SQLException {ByteArrayOutputStream baos = serializeJobData(job.getJobDataMap());PreparedStatement ps = null;int insertResult = 0;try {ps = conn.prepareStatement(rtp(INSERT_JOB_DETAIL));ps.setString(1, job.getKey().getName());ps.setString(2, job.getKey().getGroup());ps.setString(3, job.getDescription());ps.setString(4, job.getJobClass().getName());setBoolean(ps, 5, job.isDurable());setBoolean(ps, 6, job.isConcurrentExectionDisallowed());setBoolean(ps, 7, job.isPersistJobDataAfterExecution());setBoolean(ps, 8, job.requestsRecovery());setBytes(ps, 9, baos);insertResult = ps.executeUpdate();} finally {closeStatement(ps);}return insertResult;}注意:JobDataMap序列化后以Blob形式存储到数据库中StdJDBCConstants中执⾏sql如下:String INSERT_JOB_DETAIL = "INSERT INTO "+ TABLE_PREFIX_SUBST + TABLE_JOB_DETAILS + " ("+ COL_SCHEDULER_NAME + ", " + COL_JOB_NAME+ ", " + COL_JOB_GROUP + ", " + COL_DESCRIPTION + ", "+ COL_JOB_CLASS + ", " + COL_IS_DURABLE + ", "+ COL_IS_NONCONCURRENT + ", " + COL_IS_UPDATE_DATA + ", "+ COL_REQUESTS_RECOVERY + ", "+ COL_JOB_DATAMAP + ") " + " VALUES(" + SCHED_NAME_SUBST + ", ?, ?, ?, ?, ?, ?, ?, ?, ?)";2.2.2 查询JobDetail强调⼀下,因JobDetail中的JobDataMap是以Blob形式存放到数据库中的(也可以通过useProperties属性修改成string存储,默认是false,Blob形式存储),所以查询时需要特殊处理:StdJDBCDelegate.java/*** <p>* Select the JobDetail object for a given job name / group name.* </p>** @param conn* the DB Connection* @return the populated JobDetail object* @throws ClassNotFoundException* if a class found during deserialization cannot be found or if* the job class could not be found* @throws IOException* if deserialization causes an error*/public JobDetail selectJobDetail(Connection conn, JobKey jobKey,ClassLoadHelper loadHelper)throws ClassNotFoundException, IOException, SQLException {PreparedStatement ps = null;ResultSet rs = null;try {ps = conn.prepareStatement(rtp(SELECT_JOB_DETAIL));ps.setString(1, jobKey.getName());ps.setString(2, jobKey.getGroup());rs = ps.executeQuery();JobDetailImpl job = null;if (rs.next()) {job = new JobDetailImpl();job.setName(rs.getString(COL_JOB_NAME));job.setGroup(rs.getString(COL_JOB_GROUP));job.setDescription(rs.getString(COL_DESCRIPTION));job.setJobClass( loadHelper.loadClass(rs.getString(COL_JOB_CLASS), Job.class));job.setDurability(getBoolean(rs, COL_IS_DURABLE));job.setRequestsRecovery(getBoolean(rs, COL_REQUESTS_RECOVERY));Map<?, ?> map = null;if (canUseProperties()) {map = (Map<?, ?>) getObjectFromBlob(rs, COL_JOB_DATAMAP);}if (null != map) {job.setJobDataMap(new JobDataMap(map));}}return job;} finally {closeResultSet(rs);closeStatement(ps);}}2.3 查询trigger/*** <p>* Retrieve the given <code>{@link org.quartz.Trigger}</code>.* </p>** @return The desired <code>Trigger</code>, or null if there is no* match.*/public OperableTrigger retrieveTrigger(final TriggerKey triggerKey) throws JobPersistenceException {return (OperableTrigger)executeWithoutLock( // no locks necessary for read...new TransactionCallback() {public Object execute(Connection conn) throws JobPersistenceException {return retrieveTrigger(conn, triggerKey);}});}protected OperableTrigger retrieveTrigger(Connection conn, TriggerKey key)throws JobPersistenceException {try {return getDelegate().selectTrigger(conn, key);} catch (Exception e) {throw new JobPersistenceException("Couldn't retrieve trigger: "+ e.getMessage(), e);}}StdJDBCDelegate.java/*** <p>* Select a trigger.* </p>** @param conn* the DB Connection* @return the <code>{@link org.quartz.Trigger}</code> object* @throws JobPersistenceException*/public OperableTrigger selectTrigger(Connection conn, TriggerKey triggerKey) throws SQLException, ClassNotFoundException, IOException, JobPersistenceException {PreparedStatement ps = null;ResultSet rs = null;try {OperableTrigger trigger = null;ps = conn.prepareStatement(rtp(SELECT_TRIGGER));ps.setString(1, triggerKey.getName());ps.setString(2, triggerKey.getGroup());rs = ps.executeQuery();if (rs.next()) {String jobName = rs.getString(COL_JOB_NAME);String jobGroup = rs.getString(COL_JOB_GROUP);String description = rs.getString(COL_DESCRIPTION);long nextFireTime = rs.getLong(COL_NEXT_FIRE_TIME);long prevFireTime = rs.getLong(COL_PREV_FIRE_TIME);String triggerType = rs.getString(COL_TRIGGER_TYPE);long startTime = rs.getLong(COL_START_TIME);long endTime = rs.getLong(COL_END_TIME);String calendarName = rs.getString(COL_CALENDAR_NAME);int misFireInstr = rs.getInt(COL_MISFIRE_INSTRUCTION);int priority = rs.getInt(COL_PRIORITY);Map<?, ?> map = null;if (canUseProperties()) {map = getMapFromProperties(rs);} else {map = (Map<?, ?>) getObjectFromBlob(rs, COL_JOB_DATAMAP);}Date nft = null;if (nextFireTime > 0) {nft = new Date(nextFireTime);}Date pft = null;if (prevFireTime > 0) {pft = new Date(prevFireTime);}Date startTimeD = new Date(startTime);Date endTimeD = null;if (endTime > 0) {endTimeD = new Date(endTime);}if (triggerType.equals(TTYPE_BLOB)) {rs.close(); rs = null;ps.close(); ps = null;ps = conn.prepareStatement(rtp(SELECT_BLOB_TRIGGER));ps.setString(1, triggerKey.getName());ps.setString(2, triggerKey.getGroup());rs = ps.executeQuery();if (rs.next()) {trigger = (OperableTrigger) getObjectFromBlob(rs, COL_BLOB);}}else {TriggerPersistenceDelegate tDel = findTriggerPersistenceDelegate(triggerType);throw new JobPersistenceException("No TriggerPersistenceDelegate for trigger discriminator type: " + triggerType);TriggerPropertyBundle triggerProps = null;try {triggerProps = tDel.loadExtendedTriggerProperties(conn, triggerKey);} catch (IllegalStateException isex) {if (isTriggerStillPresent(ps)) {throw isex;} else {// QTZ-386 Trigger has been deletedreturn null;}}TriggerBuilder<?> tb = newTrigger().withDescription(description).withPriority(priority).startAt(startTimeD).endAt(endTimeD).withIdentity(triggerKey).modifiedByCalendar(calendarName).withSchedule(triggerProps.getScheduleBuilder()).forJob(jobKey(jobName, jobGroup));if (null != map) {ingJobData(new JobDataMap(map));}trigger = (OperableTrigger) tb.build();trigger.setMisfireInstruction(misFireInstr);trigger.setNextFireTime(nft);trigger.setPreviousFireTime(pft);setTriggerStateProperties(trigger, triggerProps);}}return trigger;} finally {closeResultSet(rs);closeStatement(ps);}}执⾏的sql:String SELECT_TRIGGER = "SELECT * FROM "+ TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " WHERE "+ COL_SCHEDULER_NAME + " = " + SCHED_NAME_SUBST+ " AND " + COL_TRIGGER_NAME + " = ? AND " + COL_TRIGGER_GROUP + " = ?";和JobDetail⼀样,也存在Blob的问题,不再赘述。

quartz-scheduler 分布式原理 -回复

quartz-scheduler 分布式原理 -回复

quartz-scheduler 分布式原理-回复QuartzScheduler 分布式原理QuartzScheduler 是一个开源的Job 调度框架,支持分布式部署。

它可以帮助开发人员创建和管理多个定时任务,确保任务在指定时间内自动执行。

在分布式环境下,QuartzScheduler 使用一套高效的机制进行任务调度和管理,以保证任务按时执行,并能够扩展和容错。

本文将详细介绍QuartzScheduler 的分布式原理,以及它是如何实现任务的分布式调度和管理的。

一、QuartzScheduler 的基础概念在深入探究QuartzScheduler 的分布式原理之前,让我们先了解一些基础概念:1. Job(任务):表示要执行的具体工作或逻辑。

Job 可以是一个类或接口,实现了execute 方法。

2. Trigger(触发器):定义了触发Job 执行的时间规则。

例如,希望每天晚上8 点执行一次的任务,可以使用一个触发器来定义。

3. Scheduler(调度器):负责调度和管理Job 的执行。

它可以注册一个或多个Job,并为每个Job 分配一个或多个触发器。

二、QuartzScheduler 的分布式架构QuartzScheduler 的分布式架构由以下五个核心组件组成:1. JobStore(任务存储):负责存储任务和触发器的信息。

它可以使用不同的存储方式,如内存、数据库等。

2. Scheduler(调度器):负责任务的调度和管理。

它可以管理一个或多个JobStore,支持分布式部署。

3. ThreadPool(线程池):用于执行Job 的线程池。

线程池根据调度器配置的并发数和任务类型来管理线程。

4. Job(任务):表示要执行的具体工作或逻辑。

Job 可以是一个类或接口,实现了execute 方法。

5. Trigger(触发器):定义了触发Job 执行的时间规则。

例如,希望每天晚上8 点执行一次的任务,可以使用一个触发器来定义。

定时任务 quartz原理

定时任务 quartz原理

定时任务 quartz原理
Quartz是一个开源的作业调度框架,主要用于在Java应用程序中实现定时任务调度。

其原理涉及到几个重要的概念和组件,包括调度器(Scheduler)、作业(Job)、触发器(Trigger)和调度工厂(SchedulerFactory)等。

首先,Quartz的核心是调度器(Scheduler),它负责管理和协调所有的作业调度任务。

调度器通过调度工厂(SchedulerFactory)创建,并且可以通过调度器工厂配置不同的参数,比如线程池大小、作业存储等。

其次,作业(Job)是需要被调度的任务,它们是通过实现Job 接口来定义具体的执行逻辑。

在Quartz中,作业可以是简单的Java类,也可以是通过Spring框架管理的Bean。

触发器(Trigger)用于定义作业的调度规则,比如何时执行、执行频率等。

Quartz提供了多种类型的触发器,包括简单触发器、Cron触发器等,可以满足不同的调度需求。

Quartz的原理是基于调度器定期触发触发器,触发器再去执行
与之关联的作业。

当触发器被触发时,调度器会根据作业的定义调用相应的执行逻辑。

Quartz还提供了持久化机制,可以将作业和触发器的状态信息存储在数据库中,保证作业调度的可靠性。

总的来说,Quartz的原理是通过调度器、作业和触发器组合实现作业调度和执行,同时提供了灵活的配置和持久化机制,使得它成为一个强大而灵活的定时任务调度框架。

希望这些信息能够帮助你更好地理解Quartz的原理。

C#中Quartz的简单易懂定时任务实现

C#中Quartz的简单易懂定时任务实现

C#中Quartz的简单易懂定时任务实现作为⼀个优秀的开源调度框架,Quartz 具有以下特点:1. 强⼤的调度功能,例如⽀持丰富多样的调度⽅法,可以满⾜各种常规及特殊需求;2. 灵活的应⽤⽅式,例如⽀持任务和调度的多种组合⽅式,⽀持调度数据的多种存储⽅式;3. 分布式和集群能⼒,Terracotta 收购后在原来功能基础上作了进⼀步提升。

另外,作为 Spring 默认的调度框架,Quartz 很容易与 Spring 集成实现灵活可配置的调度功能。

quartz调度核⼼元素:1. Scheduler:任务调度器,是实际执⾏任务调度的控制器。

在spring中通过SchedulerFactoryBean封装起来。

2. Trigger:触发器,⽤于定义任务调度的时间规则,有SimpleTrigger,CronTrigger,DateIntervalTrigger和NthIncludedDayTrigger,其中CronTrigger⽤的⽐较多,本⽂主要介绍这种⽅式。

CronTrigger在spring中封装在CronTriggerFactoryBean中。

3. Calendar:它是⼀些⽇历特定时间点的集合。

⼀个trigger可以包含多个Calendar,以便排除或包含某些时间点。

4. JobDetail:⽤来描述Job实现类及其它相关的静态信息,如Job名字、关联监听器等信息。

在spring中有JobDetailFactoryBean和MethodInvokingJobDetailFactoryBean两种实现,如果任务调度只需要执⾏某个类的某个⽅法,就可以通过MethodInvokingJobDetailFactoryBean来调⽤。

5. Job:是⼀个接⼝,只有⼀个⽅法void execute(JobExecutionContext context),开发者实现该接⼝定义运⾏任务,JobExecutionContext类提供了调度上下⽂的各种信息。

org.quartz.job原理

org.quartz.job原理

org.quartz.job原理Quartz是一个用于定时作业调度的开源框架,提供了一个强大的集成性和灵活性,支持复杂的作业调度需求,是企业级应用中使用较多的定时任务框架之一。

其中,org.quartz.job是Quartz定时作业调度中的一个非常重要的核心部分,它提供了一种标准的接口,被用于实现实际的业务作业逻辑。

org.quartz.job的原理是通过JobDetail和Trigger两个核心概念来管理调度作业的,其中JobDetail表示一个具体的作业任务,而Trigger则表示调度的时间规则。

具体来说,一个JobDetail对象代表一个被调度的作业实例,而它所包含的作业类是实际完成业务逻辑的实现。

因此,JobDetail可以被视为作业实例的模板,它包括作业名称、作业执行时所用的类、作业执行时所需的参数等信息。

而Trigger则表示调度的时间规则,也称为触发器。

它定义了作业执行的时间,通常包括触发器类型、开始时间、结束时间、触发频率等信息。

例如,simple trigger是最常用的触发器类型之一,它基于指定的执行时间和执行次数来调度作业执行。

在实际应用中,org.quartz.job具有很好的灵活性。

通过使用JobDataMap可以向JobDetail、Trigger和Scheduler传递参数或对象。

此外,Quartz还提供了一些简单易用的API,允许开发人员根据实际的业务需求,快速、灵活地实现定时作业调度。

总的来说,org.quartz.job是Quartz定时作业调度中最为核心的组件之一,它提供了一个标准的接口用于实现实际的作业逻辑,并能够很好地管理调度作业的时间规则。

这些功能的结合,使得Quartz定时任务调度框架成为了企业级应用中非常重要的一部分。

quartz原理

quartz原理

quartz原理
Quartz是一个开源的定时器框架,它可以在你指定的时间做出一定的行动。

1. Quartz的基本原理:
Quartz的核心是一个Job Scheduler,它的最核心的任务就是调度Job:当某个
Job到达了调度的时间时,Scheduler将会对它进行触发(trigger),从而Job被执行。

Quartz还支持一个叫JobStore的持久层,它的作用是存储Job的信息,包括
Job的名字,它的时间表,它被调度的相关信息等等。

2. Quartz的工作流程:
Quartz定时器的执行流程大致如下:
(1) Scheduler创建Job和Trigger,放入JobStore。

(2) Scheduler发现有新的Job待调度。

(3) Scheduler根据Job和Trigger的调度要求计算出调度时间,并将其放入JobStore和时间表中。

(4) Scheduler检查时间表,发现有到达调度时间的Job,将其触发执行。

(5) 当Job执行完毕,调度时间驱动的任务就完成了。

3. Quartz的优势:
(1) 高可用:Quartz的分布式线程是特别适合做服务器集群的;
(2) 高性能:Quartz非常灵活,可以用在需要定期批处理的大型系统中;
(3) 灵活的调度配置:可以根据自己的需要设置调度时长和重复次数;
(4) 支持数据库存储:可以把任务信息存储在数据库中,支持任务调度持久化;
(5) 多种调度模式支持:支持CRON表达式来指定任务调度时间,可以按照每秒、每分、每日、每月、指定一段时间调度等等。

quartz框架原理

quartz框架原理

quartz框架原理Quartz是一个开源的作业调度框架,它提供了一种可靠的方式来安排任务,实现定期任务的自动执行和触发,它主要包括Quartz 核心框架,Scheduling SPI(服务提供者接口),JobStore,JobDetail 和Triggers。

Quartz可以帮助我们更加灵活、高效地实现任务调度。

一、 Quartz核心框架Quartz核心框架是Quartz调度系统的引擎,提供了一系列接口和功能,它可以实现任务的调度。

Quartz可以自动创建和删除定期任务,既可以使用表达式配置定期任务,也可以使用Calender类来配置任务的运行时间,以及可以按照定制的指定任务为基准来设置任务的运行。

二、 Scheduling SPI(服务提供者接口)Scheduling SPI(服务提供者接口)是Quartz的核心接口,它提供了一系列接口,用来把Quartz的本地任务和远程任务两者结合起来,并允许客户端调用服务端中的Quartz应用程序。

三、 JobStoreJobStore是Quartz中用于存储任务和触发器的模块,它包括RAMJobStore和JDBCJobStore,RAMJobStore将所有的任务和触发器存储在内存中,启动时可以加载,但不能持久化;而JDBCJobStore 就可以将任务和触发器加载到数据库中,可以持久化存储,也可以将任务增加到数据库中,它是一种更可靠的调度方式。

四、 JobDetailJobDetail是Quartz中一个重要的接口,它封装了任务本身,它封装了任务的相关配置信息,如任务的类名和方法名,任务的输入参数,任务的类型等,它可以将这些配置信息保存到JobDataMap中,用于在任务执行时获取。

这样可以将任务本身和任务的执行分离,使用起来更加方便。

五、 TriggersTrigger是Quartz的一个重要的概念,它定义任务的触发方式,包括任务的开始时间,结束时间以及执行的条件,Quartz提供了多种类型的触发器,例如SimpleTrigger和CronTrigger,可以根据不同的条件来定义任务的触发,从而实现定期任务的自动调度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

核心概念
1.Job:Job是任务执行的流程,是一个类
2.JobDetail:JobDetail是Job是实例,是一个对象,包含了该实例的执行计划和所需要的数据
3.Trigger:Trigger是定时器,决定任务何时执行
4.Scheduler:调度器,调度器接受一组JobDetail+Trigger即可安排一个任务,其中一个JobDetail可以关联多个Trigger 实例
1.初始化:
1
2
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
当程序退出时,应该主动调用shutdown()方法关闭该调度器。

2.Job:
一个Job类需要实现org.quartz.Job接口,这个接口值需要实现一个方法即可:
1 void execute(JobExecutionContext context) throws JobExecutionException
context是重要的上下文,可以访问到关联的JobDetail对象和本次触发的Trigger对象,以及在此之上设定的数据。

3.JobDetail:
可以使用JobBuilder来构建一个JobDetail对象:
1
2
3
4
5
6
7
JobDetail job = JobBuilder.newJob(MyJob.class) // MyJob是我实现的Job类
.withIdentity("myjob") // 可以给该JobDetail起一个id,便于之后的检索
.requestRecovery() // 执行中应用发生故障,需要重新执行
.storeDurably() // 即使没有Trigger关联时,也不需要删除该JobDetail
.usingJobData("key1", "value1")
.usingJobData("key2", "value2") // 以Key-Value形式关联数据
.build();
Quartz因为考虑到有些任务不是幂等的,不可以多次重复执行,所以默认没有开启“requestRecovery”。

当确认业务中允许一次任务执行两次的情况下,可以开启该选项,则任务肯定不会因为应用停止而漏调用,但缺点就是,有可能会重复调用。

每个JobDetail内都有一个Map,包含了关联到这个Job的数据,在Job类中,可以通过context取出该数据,进行业务流程处理。

4.Trigger:
可以使用TriggerBuilder来构建一个Trigger对象:
1
2
3
4
5
6
7
8
Trigger trigger = TriggerBuilder.newTrigger()
.forJob("myjob") // 关联上述的JobDetail
.withIdentity("myjob-trigger1") // 给该Trigger起一个id
.startAt(DateBuilder.futureDate(20, IntervalUnit.SECOND)) // 延迟20秒开始
.withSchedule(SimpleScheduleBuilder.repeatMinutelyForever()) // 每分钟触发一次,无限循环
.usingJobData("key3", "value3")
.usingJobData("key4", "value4") // 以Key-Value形式关联数据
.build();
5.设定:
因为上述的Trigger已经关联了JobDetail,可以使用
1 scheduler.scheduleJob(trigger);
把这一组JobDetail和Trigger加载到调度器上,接下来就会按照计划执行Job任务。

6.配置文件:
配置文件不是必须的,Quartz对配置项都是有默认值的,当需要自定义的时候,可以在classpath路径下放一个quartz.properties文件,Quartz的StdSchedulerFactory在启动时会自动加载该配置文件。

比较值得关注的是这两个配置项:
1
2
org.quartz.threadPool.threadCount=50
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=50
第一个配置项是线程池里的线程数,默认值是10,当执行任务会并发执行多个耗时任务时,要根据业务特点选择线程池的大小。

第二个配置是,当检查某个Trigger应该触发时,默认每次只Acquire一个Trigger,(为什么要有Acquire的过程呢?是为了防止多线程访问的情况下,同一个Trigger被不同的线程多次触发)。

尤其是使用JDBC JobStore时,一次Acquire就是一个update语句,尽可能一次性的多获取几个Trigger,一起触发,当定时器数量非常大的时候,这是个非常有效的优化。

当定时器数量比较少时,触发不是极为频繁时,这个优化的意义就不大了。

持久化
如果定时器在业务中属于关键数据,需要在故障重启后恢复状态,则需要把Quartz配置为持久化模式。

默认情况下,所有定时任务和数据都保存在内存中,在应用重启后状态会消失。

JobStore决定了Quartz如何存储任务和触发器,默认值是org.quartz.simpl.RAMJobStore,我们需要把它配置为org.quartz.impl.jdbcjobstore.JobStoreTX,即可以使用JDBC数据源,把状态持久化到关系型数据库中。

用H2数据库进行举例,配置文件如下:
1
2
3
4
5
6
7
8
org.quartz.dataSource.DATA_SOURCE_NAME.driver=org.h2.Driver
org.quartz.dataSource.DATA_SOURCE_NAME.URL=jdbc:h2:quartz;MVCC=TRUE
org.quartz.dataSource.DATA_SOURCE_er=sa
org.quartz.dataSource.DATA_SOURCE_NAME.password=
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource=DATA_SOURCE_NAME
# eDBLocks=true
Quartz为了保证多线程下的一致性,使用了锁,但是使用了使用Lock表里的一行记录来模拟锁的形式来实现的,其实性能很糟糕,还不如使用默认的基于Java 的Monitor锁的效果好,所以我注释掉了这个配置项。

之后,打开quartz-x.x.x.tar.gz包内的docs/dbTables文件夹内有各种数据库下的建表语句,直接在数据库中执行,把表先建好。

配置文件中增加上述对JobStore的设定后,代码不用修改一行,所有的任务和触发器已经是持久化的了,当应用停机重启后,错过的(misfire)任务和上次正在执行的(recovery)任务都会回复状态,如果JobDetail指定了requestRecovery,上次执行中,但没有执行完毕的任务会重新执行一遍。

相关文档
最新文档