溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Quartz是什么

發(fā)布時(shí)間:2021-09-13 15:34:37 來源:億速云 閱讀:181 作者:柒染 欄目:大數(shù)據(jù)

這篇文章給大家介紹Quartz是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

Quartz是一個(gè)完全由Java編寫的開源作業(yè)調(diào)度框架,為在Java應(yīng)用程序中進(jìn)行作業(yè)調(diào)度提供了簡單卻強(qiáng)大的機(jī)制。

Quartz核心概念

Job:表示一個(gè)工作,要執(zhí)行的具體內(nèi)容,此接口中只有一個(gè)方法:void execute(JobExecutionContext context)

JobDetail:表示一個(gè)具體的可執(zhí)行的調(diào)度程序,Job是這個(gè)可執(zhí)行程序所需要執(zhí)行的內(nèi)容,另外,JobDetail還包含了這個(gè)任務(wù)調(diào)度的方案和策略。

Trigger:表示一個(gè)調(diào)度參數(shù)的配置,什么時(shí)候去調(diào)。

Scheduler:表示一個(gè)調(diào)度容器,一個(gè)調(diào)度容器中可以注冊多個(gè)JobDetail 和 Trigger。

Quartz運(yùn)行環(huán)境

Quartz可以運(yùn)行嵌入在另一個(gè)獨(dú)立式應(yīng)用程序。

Quartz可以在應(yīng)用程序服務(wù)器(或Servlet容器)內(nèi)被實(shí)例化,并且參與XA事務(wù)。

Quartz可以作為一個(gè)獨(dú)立的程序運(yùn)行(其自己的JVM內(nèi)),可以通過RMI使用。

Quartz可以被實(shí)例化,作為獨(dú)立的項(xiàng)目集群(負(fù)載平衡和故障轉(zhuǎn)移功能),用于作業(yè)的執(zhí)行。

public class Quickstart {
   public static void main(String[] args) {
       try {
           Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
           scheduler.start();
           scheduler.shutdown();
       } catch (SchedulerException e) {
           e.printStackTrace();
       }
   }
}

運(yùn)行日志如下:

14:53:00.764 [main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor

14:53:00.790 [main] INFO org.quartz.simpl.SimpleThreadPool - Job execution threads will use class loader of thread: main

14:53:00.856 [main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl

14:53:00.856 [main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.0 created.

14:53:00.857 [main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.

14:53:00.858 [main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'

 Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.

 NOT STARTED.

 Currently in standby mode.

 Number of jobs executed: 0

 Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.

 Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.



14:53:00.858 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'

14:53:00.858 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.0

14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.

14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.

14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.

14:53:00.859 [main] DEBUG org.quartz.simpl.SimpleThreadPool - Shutting down threadpool...

14:53:00.859 [main] DEBUG org.quartz.simpl.SimpleThreadPool - Shutdown of threadpool complete.

14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete.

14:53:01.303 [DefaultQuartzScheduler_Worker-1] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.303 [DefaultQuartzScheduler_Worker-2] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.304 [DefaultQuartzScheduler_Worker-6] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.304 [DefaultQuartzScheduler_Worker-5] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.305 [DefaultQuartzScheduler_Worker-9] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.323 [DefaultQuartzScheduler_Worker-3] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.338 [DefaultQuartzScheduler_Worker-7] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.338 [DefaultQuartzScheduler_Worker-8] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.338 [DefaultQuartzScheduler_Worker-4] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

14:53:01.338 [DefaultQuartzScheduler_Worker-10] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.

Scheduler的生命周期

從SchedulerFactory創(chuàng)建它時(shí)開始,到Scheduler調(diào)用shutdown()方法時(shí)結(jié)束;Scheduler被創(chuàng)建后,可以增加、刪除和列舉Job和Trigger,以及執(zhí)行它的與調(diào)度相關(guān)的操作,但是,Scheduler只有在調(diào)用start()方法后,才會(huì)真正地觸發(fā)Trigger(即執(zhí)行job)。

Job和Trigger的聯(lián)系

一個(gè)Job就是實(shí)現(xiàn)了Job接口的類,當(dāng)Job的一個(gè)Trigger被觸發(fā)時(shí),execute()方法由調(diào)用程序的一個(gè)工作線程調(diào)用,傳遞給execute()方法的JobExecutionContext對象向作業(yè)實(shí)例提供“運(yùn)行時(shí)”環(huán)境,一個(gè)Job的Trigger被觸發(fā)后,execute()方法會(huì)被Scheduler的一個(gè)工作線程調(diào)用,傳遞給execute()方法的JobExecutionContext對象中保存著該Job運(yùn)行時(shí)的一些信息。

Trigger是用于觸發(fā)Job執(zhí)行的,當(dāng)調(diào)度一個(gè)Job時(shí),創(chuàng)建一個(gè)Trigger實(shí)例,設(shè)置調(diào)度相關(guān)的屬性,Quartz自帶了各種不同類型的Trigger,最常用的主要是SimpleTrigger和CronTrigger。

Job和Trigger的Key

將Job和Trigger注冊到Scheduler時(shí),可以為它們設(shè)置key,配置其身份屬性,Job和Trigger的Key可以用于將Job和Trigger放到不同的分組里,然后基于分組進(jìn)行操作。注意:同一個(gè)分組下的Job和Trigger的名稱必須唯一,即一個(gè)Job或Trigger的Key由名稱(name)和分組(group)組成。

問題:為什么既有Job又有Trigger呢?

很多任務(wù)調(diào)度器并不區(qū)分Job和Trigger,有些調(diào)度器只是簡單地通過一個(gè)執(zhí)行時(shí)間和一些Job標(biāo)識(shí)符來定義一個(gè)Job;其它的一些調(diào)度器將Quartz的Job和Trigger對象合二為一。Quartz的開發(fā)者認(rèn)為將調(diào)度和要調(diào)度的任務(wù)分離是合理的,例如:Job被創(chuàng)建后,可以保存在Scheduler中,與Trigger是獨(dú)立的,同一個(gè)Job可以有多個(gè)Trigger,Job和Trigger之間是松耦合的,當(dāng)與Scheduler中的Job關(guān)聯(lián)的Trigger都過期了,可以配置Job稍后被重新調(diào)度,而不是重新定義Job,還有,可以修改或者替換Trigger,而不用重新定義與之關(guān)聯(lián)的Job。

Job和JobDetail的聯(lián)系

JobDetail實(shí)例是通過JobBuilder類創(chuàng)建的,在Quartz的描述語言中,JobDetail被稱為“Job定義”或者“JobDetail實(shí)例”,一個(gè)正在執(zhí)行的Job被稱為“Job實(shí)例”,所以,當(dāng)我們使用“Job”時(shí),一般指代的是Job定義,或者JobDetail;當(dāng)我們提到實(shí)現(xiàn)Job接口的類時(shí),通常使用“Job類”。

Job狀態(tài)與并發(fā)

Job的狀態(tài)數(shù)據(jù)和并發(fā)性,有一些地方需要注意,在Job類上可以加上一些注解來避免問題:

@DisallowConcurrentExecution:將該注解加到Job類上,告訴Quartz不要并發(fā)地執(zhí)行同一個(gè)Job定義,需要注意:該注解雖然加在Job類上,但實(shí)際上是作用在JobDetail上的。

@PersistJobDataAfterExecution:將該注解加到Job類上,告訴Quartz在成功執(zhí)行了job類的execute方法后(沒有發(fā)生任何異常),更新JobDetail中JobDataMap的數(shù)據(jù),使得該Job(即JobDetail)在下一次執(zhí)行的時(shí)候,JobDataMap中是更新后的數(shù)據(jù),而不是更新前的舊數(shù)據(jù)。和 @DisallowConcurrentExecution注解一樣,該注解雖然加在Job類上,但實(shí)際上是作用在JobDetail上的。

如果你使用了@PersistJobDataAfterExecution注解,我們強(qiáng)烈建議你同時(shí)使用@DisallowConcurrentExecution注解,因?yàn)楫?dāng)同一個(gè)Job(JobDetail)的兩個(gè)實(shí)例被并發(fā)執(zhí)行時(shí),由于競爭,JobDataMap中存儲(chǔ)的數(shù)據(jù)很可能是不確定的。

JobDataMap

JobDataMap是Java Map接口的一個(gè)實(shí)現(xiàn),可以包含不限量的(序列化的)數(shù)據(jù)對象,在Job實(shí)例執(zhí)行的時(shí)候,可以使用其中的數(shù)據(jù)。

如果使用持久化的存儲(chǔ)機(jī)制,在決定JobDataMap中存放什么數(shù)據(jù)的時(shí)候需要小心,因?yàn)镴obDataMap中存放的對象都會(huì)被序列化,因而可能會(huì)導(dǎo)致類的版本不一致的問題。

JobExecutionException

是execute方法中僅允許拋出一種類型的異常,在實(shí)際應(yīng)用中,應(yīng)該將execute方法中的所有內(nèi)容都放到一個(gè)”try-catch”塊中,以便知道如何來處理發(fā)生的異常。

快速開始的完整示例

public class Quickstart {

   public static void main(String[] args) {
       try {
           Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
           scheduler.start();
           JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1")
                   .usingJobData("name", "quartz").build();
           Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow()
                   .withSchedule(simpleSchedule().withIntervalInSeconds(30).repeatForever()).build();

           scheduler.scheduleJob(job, trigger);
           try {
               Thread.sleep(1000L * 60L * 10L);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           scheduler.shutdown();
       } catch (SchedulerException e) {
           e.printStackTrace();
       }
   }
}

public class HelloJob implements Job {
   @Override
   public void execute(JobExecutionContext context) throws JobExecutionException {
       try {
           JobDetail job = context.getJobDetail();
           String name = job.getJobDataMap().getString("name");
           System.out.println("hello " + name + " at " + new Date());
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

關(guān)于Quartz是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI